记得那会刚学JavaScript的时候,注册事件都喜欢用最原始的方式(以下说的IE,都为早版本的IE,比如6,7,8)
<input type="button" id="btn" value="点我" />
var btn=document.getElementById("btn"); btn.onclick=function(){ alert("点击了btn"); }
这样的确是没有问题,所有浏览器都支持。但是,有一点不好的是,多人开发的时候,别人也可能这样给btn注册了一个click事件,然后我在这样注册一个click事件,别人注册的事件就被我的给覆盖了。看人家jQuery,不论注册多少个事件,都会执行。那他是怎么实现的呢
if (window.addEventListener) { //标准事件模型 btn.addEventListener("click", function () { alert("标准事件模型 点击 btn"); }, false); btn.addEventListener("click", function () { alert("标准事件模型 点击 btn2次"); }, false); } else { //IE事件模型 btn.attachEvent("onclick", function () { alert("IE事件模型 点击 btn"); }); btn.attachEvent("onclick", function () { alert("IE事件模型 点击 btn2次"); }); }
看我给btn注册了两个事件,事件会依次执行(IE里会反过来,后注册的先执行)。标准事件模型最后一个参数代表是否在事件捕获阶段触发执行函数,为了兼容IE,一般都传false,因为IE不支持事件捕获,只支持事件冒泡。
如果要想把注册的事件删除呢,其实删除是可以的,只是上面的监听方法是匿名的,连个名字都没有,所以,这里就删不了
var fnClick=function(){alert("点击 btn");}; if (window.addEventListener) { //标准事件模型 btn.addEventListener("click", fnClick, false); btn.removeEventListener("click", fnClick, false); } else { //IE事件模型 btn.attachEvent("onclick", fnClick ); btn.detachEvent("onclick", fnClick ); }
这里,这个事件是不会执行的,因为事件注册之后就被删除了
有时候有这样的情况,在一个闭包里,给按钮注册了一个click事件,绑定处理函数A,且假定A为私有的。在另一个闭包里,我想执行那个函数A,但是访问不到,怎么办呢。
事件虽然是私有的,但是按钮是全局且公共的呀,可以手动触发按钮的click事件嘛,这样,就能间接执行函数A了
if (window.addEventListener) { //标准事件模型 btn.addEventListener("click", function () { alert("标准事件模型 点击 btn"); }, false); //创建一个事件对象,只能用给定的字符串创建,比如 HTMLEvents MouseEvents UIEvents var evObj = document.createEvent('MouseEvents'); //初始化事件对象,initEvent只是一个通用的初始化方法,这里还可以用别的初始化方法,比如initMouseEvent,但是这个方法参数太多,我们选用通用方法 evObj.initEvent('click', true, false); //第二个参数,代表事件是否应该冒泡,第三个参数代表事件是否可以被取消 btn.dispatchEvent(evObj); //触发事件 } else { //IE事件模型 btn.attachEvent("onclick", function () { alert("IE事件模型 点击 btn"); }); btn.fireEvent('onclick'); //IE里,很简单,直接调用 fireEvent 触发事件 }
当然,初始化事件的方法,还有 initMutationEvent,initKeyboardEvent,感兴趣的可以去了解一下。其实事件模型很复杂,我也在学习中,DOM0、DOM1、DOM2、DOM3里的模型都会有出入,期望赶快更新换代吧,痛苦的前端程序猿