关于下拉菜单的一些问题

来源:3-6 改写站点导航中的下拉菜单

weixin_慕的地5241954

2019-10-11 21:27:45

一、下拉菜单1-1至2-6

1、用div设置基本html结构,设置基本css样式,保留公共的结构和样式;

2、每个不同的网页再把独有的结构和样式,添加到公共的结构和样式里面,这就是代码的复用;

3、jQuery插件形式:$.fn.extend意思是把dropdown()方法拓展到jQuery对象的 prototype上,相当于原生js中的原型模式创建对象,所以实例化一个jQuery对象的时候,它就具有了这些方法。

4、如果将事件耦合(写入)在方法内部,就没有办法做其他的事件,可以通过把回调函数以传参的方式写在方法里,把事件写在回调函数里,方法内部调用回调函数,这个方法就能做很多件事,能一定程度上实现解耦,是一种函数封装分离的思想,一个函数做一件事。(常用的方式,但是不利于多人协作,下面的方式可以多人协作)

5、下拉菜单——2-3显示和隐藏案例:

发布订阅方式(适合多人协作):发布一则消息,并不是所有人都能接收到,只有订阅了消息的人才能接收到;其实跟上面的函数封装思想一样,只是把回调函数当作一个事件,绑定到了这个对象上(通过on方法)。这个对象自己发布消息,订阅消息,但是对象上的每个方法(人)不同,对象上有个特定的方法(人)发布消息,其他的方法(人)订阅消息。

本案例中先由另一个对象$(btn)通过点击事件触发silent.show($box)方法,告诉$box对象开始发布订阅消息,然后  $box.trigger('show')发布消息,接着$box.on('show',function(){})订阅消息,执行程序,shown同理。

总结:这个发布订阅方式跟原生js中的一个对象上创建多个方法,并且多个方法之间互相可以调用相似。

6、jQuery中的data() 方法向被选元素附加数据,或者从被选元素获取数据。向被选元素附加数据:语法:$(selector).data(name,value);从被选元素中返回附加的数据。语法:$(selector).data(name)。

jQuery中的is() 方法根据选择器、元素或 jQuery 对象来检测匹配元素集合,如果这些元素中至少有一个元素匹配给定的参数,则返回 true,如果检测元素属性的值,值前面加: 。

7、css3中:blcok和none属性没有动画效果,opacity属性会占住位置,而且会响应事件,要在加visibility来解决,详情见css中的fadeOut中。所以能用css完成的操作(样式的改变)不要放在js中,意思是在css和html增加一个样式和相同的样式名,然后把样式名传入js中就可以了。

8、on方法的绑定事件事件一直被触发,on方法内部的事件也会一直触发,所以用one方法或者off解除掉。off方法触发可以取消正在执行的事件

9、去除多余的代码(相同的代码),用函数的形式把相同的代码封装成公共的方法以供调用。如何提取公共部分:先找相似部分,包括参数,这部分不用修改,然后看不同部分,如果有不同部分且是执行语句,那么就用一个函数把执行语句封装起来,然后通过回调函数的形式把这部分内容通过参数传入公共的方法,再传入回调函数之前记得要typeof检测。

10、transition.js是兼容不同浏览器的transition属性和transitionend写法的。

二、 下拉菜单2-7 

11、用height+padding设置动画时,加!important权重使样式优先级最高,一般用于js+css动画中设置样式。

12、js中用相同的方法名时,内部方法名前面加下划线_,仅供对象内部调用。初始化时要获取并设置div的高度应对各种情况(主要是没设置高度,被里面内容撑开)。

13、jQuery中封装好了淡入淡出和高度变化的动画效果,没有封装宽度变化的动画,可以用js+css3来写,只要进行初始化和判断动画执行完后的状态就行了。stop方法是暂停之前的动画。jQuery自己的动画方式(mode或者叫方法)作为参数传递时,应该用方括号方式的传递:[mode]。jQuery封装宽度变化的动画跟css3设置样式传入样式名类似,只是在jQuery中直接用css('')方法获取样式,然后用一个对象的属性来保存,再用data('name', 对象)方法来保存数据以供外部调用,因为这个对象是局部的,然后用css({'' : ''})方法初始化样式,最后用animate()方法来设置动画。

14、2-9 时间11:44,对把对象传参不是太理解,重点了解一下,已经解决。答案在前端问题中:http://class.imooc.com/course/qadetail/160235。

15、把silent、css3、js这3个方法封装到一个函数里(接口或者叫api),以供外部选择哪一种方法调用,记得设初始值和弄懂extend插件的用法。2-10最后完善:用$proxy插件传参。第一种调用方法:把封装好的api放到全局对象上以供调用。第二种调用方法:$.fn.extend()插件形式

一、下拉菜单3-2至3-4

1、用构造函数Dropdown(首字母大写)和实例化构造函数(生成对象)的方式重写dropdown,下拉菜单可以看做一个对象(构造函数实例化),菜单上有show方法和hide方法。但是有一个问题:每次实例化新的对象的时候,都会重新拷贝一份show和haide方法(意思是每个新对象都会在堆内存空间中开辟一块空间来保存show和hide,或者叫创建一个副本),而show和hide的内容是一样的,所以这些对象可以共用这两个方法,最重要的是这样做对性能是极大的浪费。

解决办法:在构造函数的原型上来写,Dropdown.prototype.show = function(){},这样做就算实例化再多次对象,也只是执行Dropdown,不会执行Dropdown.prototype.show,因为这两个方法在Dropdown.prototype原型这个对象上,实例化的对象通过__proto__属性指向原型对象(通过指针找到),并调用这两个方法,所以这两个方法并不是实例化对象本身自带的方法。

prototype和__proto__的区别:

(1)Javascript中所有的对象都是Object的实例,并继承Object.prototype的属性和方法,也就是说,Object.prototype是所有对象的爸爸。

(2)在对象创建时,就会有一些预定义的属性,其中定义函数的时候,这个预定义属性就是prototype,这个prototype是一个普通的对象。而定义普通的对象的时候,就会生成一个__proto__,这个__proto__指向的是这个对象的构造函数的prototype。而这个Dropdown函数的prototype对象构造函数是谁呢? 就是Object.prototype。

2、3-4发送消息、暴露方法以及单例没理解明白,还有按需加载

老师看看我总结的对不对。还有下面的问题

1、就是$.extend插件和$.fn.extend()插件形式的区别?

2、发送消息、暴露方法以及单例没理解明白,还有按需加载。这几点能帮我解释总结一下吗?

写回答

2回答

好帮手慕星星

2019-10-12

你好,

1、同学理解的没有问题,是执行了两次trigger。

2、在3-4视频中,test/dropdown.html中老师定义了dropdown-show事件:

http://img.mukewang.com/climg/5da1679d09b035e516260932.jpg

3、看一下执行过程,以移入为例:

http://img.mukewang.com/climg/5da1683309931cc111100349.jpg

封装的dropdown中发生的操作:

http://img.mukewang.com/climg/5da168e209068c2b12620517.jpghttp://img.mukewang.com/climg/5da169670992a7ec09480781.jpghttp://img.mukewang.com/climg/5da169fc0934dd5105720384.jpg

http://img.mukewang.com/climg/5da16ae609da208d08460800.jpghttp://img.mukewang.com/climg/5da16bbf0993b3a406960683.jpghttp://img.mukewang.com/climg/5da16c35094c154d07580742.jpghttp://img.mukewang.com/climg/5da16c670919291c05700252.jpg

触发的show事件之后,就会触发dropdown-show:

http://img.mukewang.com/climg/5da16cad0940828702350239.jpg

自己可以再理解一下这个过程。

祝学习愉快!

0

好帮手慕星星

2019-10-12

同学你好,

1、整体总结还是不错的。

下面这个总结有点不严谨:

http://img.mukewang.com/climg/5da13f5b096abd3f07560023.jpg

这两个可能看上去有一点像  但是有区别的。本案例中,只是在事件中,调用了一个方法去触发,去通知。发布和订阅都是独立的,并不是相互调用的关系。跟对象中方法相互调用不是一回事,所以不要进行对比哦。

2、参考:

(1)$.extend(jQuery.extend):把JQ当做普通的对象,定义的私有属性和方法(这些方法一般都是项目中的一些工具包或者常用的方法如$.ajax())

(2)$.fn.extend(jQuery.fn.extend):在原型上面定义方法,供JQ的实例使用。JQ实例一般都是用选择器获取到的元素集合,$(elem).aa(),这样做一般是给元素用的,我们也基于这个扩展JQ插件

3、参考下面的解释:

(1)接收消息,发送消息:

showHide.js中写了当元素到达某个状态的时候,使用trigger()方法去触发事件,如下:

http://img.mukewang.com/climg/5da137ab0944104606420425.jpghttp://img.mukewang.com/climg/5da137c9094b9af707910601.jpg

在dropdown.js中调用了showHide:

http://img.mukewang.com/climg/5da137fe0986e61205870575.jpg

所以元素达到某个状态的时候,就会执行相应的事件:

http://img.mukewang.com/climg/5da1383409d94d4807360198.jpg

e.type就是相应的事件类型,接收了消息,然后再通过trigger方法去触发绑定的事件,发送消息:

http://img.mukewang.com/climg/5da138bd0916cc8e10870105.jpg

(2)暴露方法:

不仅仅是在dropdown中使用,暴露出去让用户可以传参:

http://img.mukewang.com/climg/5da139ba09c4c79c05140224.jpg

http://img.mukewang.com/climg/5da13a1d09c058ca13370553.jpg

(3)单例模式:

只实例化一次,每次调用的时候不重复实例化,用第一次实例化后保存的值。了解一下即可:

http://img.mukewang.com/climg/5da13bee0950017512700524.jpg

可以参考其它用户手记里面的例子:

https://www.imooc.com/article/40239

(4)按需加载:

数据不是固定的,一般都通过接口从数据库里面获取,再渲染出来。这里老师用本地json进行了模拟,通过ajax进行获取再渲染。用户有移入导航项操作的时候,再获取数据进行渲染,而不是一打开页面,所有数据都显示出来,根据实际需求去显示。

自己再理解下,祝学习愉快!

0
heixin_慕的地5241954
h 3、showHide.js中data达到show状态trigger()触发'show'事件,然后dropdown.js中调用了showHide中show事件,我理解。 但是this.$layer达到show状态,又执行了trigger()方法,第二次是触发dropdown-show事件对吗?就是说用户传参进来(鼠标滑过或者点击)要触发show事件,最开始是执行showHide.js中的程序使元素变为show状态,然后通过trigger()方法执行show事件,然后再执行dropdown.js中showhide('show')方法。layer层再通过trigger()方法执行dropdown-show事件,是执行了两次trigger()方法对吗?dropdown-show事件在哪里? 暴露方法让用户传参能结合代码执行一遍完整的程序说一下嘛?不是太能理解
h019-10-12
共1条回复

0 学习 · 14456 问题

查看课程