事件处理函数中,我们通常使用this来获取当前被操作的对象。这无疑是很方便的一个特性, 但对于不同的事件绑定方式,this可能不一定是当前被操作的对象。 本文便来分析不同的方式绑定事件处理函数时,函数中this的区别。常见的事件绑定方式不外乎4种:
1. attachEvent:IE9以下(不包括IE9)的MSIE中。
2. addEventListener:支持DOM Level 2 Event的浏览器中。
3. el.onclick=function(){}:这是古老的事件绑定方式。
4. <a onclick='handle()'>:这是古老的事件绑定方式。
5. jQuery也提供了很多方法来方便地绑定事件
addEventListener是现代Web应用中绑定事件的终极方法,jQuery从版本2开始也是通过调用addEventListener来实现其事件绑定逻辑 (源码分析参见:DOM Level 2 Event与jQuery源码)。 jQuery的所有事件绑定最终调用的是on方法,参见:jQuery事件:bind、delegate、on的行为与性能。
attachEvent与addEventListener的区别
坦白地讲我从不使用attachEvent,就连jQuery也更新到了版本2,并无支持IE的习惯。但基于面试中常常问到, 还是来谈谈attachEvent与addEventListener的区别吧!它和addEventListener有何区别呢?
当然支持的浏览器不同,attachEvent在IE9以下的版本中受到支持。其它的都支持addEventListener。
参数不同。addEventListener第三个参数可以指定是否捕获,而attachEvent不支持捕获。
事件名不同。attachEvent第一个参数事件名前要加on,比如el.attachEvent('onclick', handleClick);
this不同。我们知道this总之指向当前函数的调用者,对于事件处理函数这一点较为复杂,这是本文的重点所在。
addEventListener方式的事件绑定
addEventListener的this总是当前正在处理事件的那个DOM对象。 DOM Level 2 Event Model中提到,事件处理包括捕获阶段、目标阶段和冒泡阶段 (关于捕获和冒泡机制的详情请参见DOM Level 2 Event与jQuery源码)。如下图:
图片来源:http://www.w3.org/TR/DOM-Level-3-Events/#dom-event-architecture
事件当前正在流过哪个元素,this便指向哪个元素。比如对于两级的DOM:
target与currentTarget
addEventListener的事件处理函数中this不一定指向事实上被点击的元素, 但事件处理函数的参数Event对象提供了target和currentTarget属性来区分这当前对象与目标对象。 我们可以把它们都全部输出:
可见currentTarget总是和this相同,而target指向事实上被点击的目标DOM对象。