以前看完了js和jq的冒泡捕获和事件对象event,这里看看同时使用js和jq后我最容易混淆的监听器的绑定。html
(1) js的监听器绑定解绑web
绑定监听器有两种方式:浏览器
a.on-事件type,好比onclick,onfocusdom
这种方式能够直接使用在html界面中:函数
<button onclick=’alert(‘点击成功!’)’>点击</button>
也能够在js中使用:测试
btn.onclick=function(){}; btn.setAttribute('onclick', 'doSomething()');
其实这个绑定方法有点像属性,因此能够用setAttribute设置,并且只有一个值,因此它只能绑定一个事件,后面设的值会覆盖前面的值。this
若是进行解绑,直接用空值覆盖,若是想要阻止事件的继续触发能够用onclick=“return false”阻止spa
b.target.addEventListener().net
最标准的的绑定监听器的方式,能够绑定多个监听器。也可使用removeEventListener进行解绑。设计
传入的是事件句柄,也就是不包含园括号的函数名。这样也会致使一个问题,就是这个函数你没有办法传参。Jq已经实现了传参的封装,而若是你想要在js中传参,使用模块级变量,数据记录在dom的data中等等,只能本身想办法。
c.target.attachEvent()
和addEventListener()类似,不过是ie特有的,不符合W3C标,ie不支持addEventListener,对应的解绑方法是detachEvent()。不过 ie8以上已经不支持attachEvent(),反而支持addEventListent()了。至少我测试的时候的确是不支持attachListener(),而支持addEventListener()了。
下面是一个兼容的代码(引自https://www.cnblogs.com/zhn0823/p/5821505.html):
/** * @description 事件绑定,兼容各浏览器 * @param target 事件触发对象 * @param type 事件 * @param func 事件处理函数 */ function addEvent(target, type, func) { if (target.addEventListener) //非ie 和ie9 target.addEventListener(type, func, false); else if (target.attachEvent) //ie6到ie8 target.attachEvent("on" + type, func); else target["on" + type] = func; //ie5 }; /** * @description 事件移除,兼容各浏览器 * @param target 事件触发对象 * @param type 事件 * @param func 事件处理函数 */ function removeEvent(target, type, func){ if (target.removeEventListener) target.removeEventListener(type, func, false); else if (target.detachEvent) target.detachEvent("on" + type, func); else target["on" + type] = null; };
二、 jq的监听器绑定解绑
jQuery中提供了四种事件监听方式,分别是bind、live、delegate、on,对应的解除监听的函数分别是unbind、die、undelegate、off。而这几个函数的前面能够是一个jq对象集,有几个对象就帮几个对象绑定监听器,如$(‘#myol li’).on()会帮该ol下全部的li绑定监听器。
其余三种方法都是经过触发on实现的,官方推荐的尽可能使用on,可是其余方法也有各自的优点。看源码看得我头疼,那就不纠结了,暂时只分析各自的使用优点应该就好了。
<1>on(type,[selector],[data],fn,/*INTERNAL*/ one)
其中,
type就是事件名称,好比“click”“dbclick”
[selector]不懂,可是能够不用传
[data]是能够传的数据、参数,函数里面用event.data来获取
Fn是绑定的函数句柄
one是用来区分只触发一次的监听器,当one===1时,只触发一次
on为全部指定元素添加监听器,若是元素用on绑定监听器以后制定的元素有数量的增长,不会为新增长的元素绑定监听器。
<2>bind(type,[data],function(eventObject))
这个方法就几乎与on如出一辙了,只是剔除了selector的传入,所存在的缺点也有
<3>live(type, [data], fn)
这个方法就克服了对新增元素无效的问题,它是将监听器绑定在this.context(通常是document)上面,而后根据事件委托机制,根据currenttarget来获取节点进行监听事件。可是看效率来讲,不必的时候仍是使用on吧
<4>delegate(selector,type,[data],fn)
参数多了一个selector,用来指定触发事件的目标元素,监听器将被绑定在调用此方法的元素上。这个也能够克服新增元素无效的问题,由于事件是绑定在父元素身上的。on方法中的selector应该就是专门为这个函数设计的吧?
$('#myol').delegate('li','click',getHtml);
如上语句,点击每一个li会触发getHtml显示li里的文字,可是输出的currentTarget是ol,target是点击的li,
三、 js监听器的触发
target.dispatchEvent(event);
该方法在当前节点上触发指定事件,从而触发监听函数的执行。该方法返回一个布尔值,只要有一个监听函数调用了Event.preventDefault(),则返回值为false,不然为true。
var event = new Event('click'); add.dispatchEvent(event);
或者
var evt = document.createEvent( 'HTMLEvents' ); evt.initEvent('click', true, true); add.dispatchEvent(evt);
旧版ie使用fireEvent(),事实上新版ie已经支持其余浏览器绑定解绑触发监听器的函数了,不想管了。
遗留问题:可是使用dispathchEvent()触发超连接的操做上有问题,谷歌认为:“点击超连接下载文件”是一个“默认响应”,而默认响应不该由脚本触发,因此从M53版本开始禁止全部由脚本触发的默认响应。火狐谷歌都不支持触发超连接、ie支持。具体下面再具体讨论。
Chrome浏览器M53更新后超连接的dispatchEvent(evt)方法没法触发文件下载:
https://www.cnblogs.com/ljzc002/p/6003214.html
四、 jq监听器的触发
$(selector).trigger(event,[param1,param2,...])
同时,不支持触发超连接,在ie中也不触发
参考:
一、js
http://www.cnblogs.com/dacuotecuo/p/3510823.html
http://www.javashuo.com/article/p-hvjgcwcc-gp.html
http://www.javashuo.com/article/p-txhguyxm-gu.html
https://blog.csdn.net/namejs/article/details/50885698
http://www.javashuo.com/article/p-htbuxoct-gm.html
二、jq
https://blog.csdn.net/lookbackward/article/details/78363997
http://www.cnblogs.com/webFrontDev/p/3509775.html
三、js触发