我们都知道,在javascript的DOM操作中,事件监听器与内联事件这两个方法可以实现相同的功能,那到底他们有何区别呢?
事件监听器Event Listeners (addEventListener and IE's attachEvent)
<pre>
element.attachEvent()只能使用于IE8及以下浏览器;
element.attachEvent('onclick', function() { /* do stuff here*/ });
</pre>
在大多数其它的其它浏览器包括IE9+,你可以按如下格式使用:
element.addEventListener('click', function() { /* do stuff here*/ }, false);
通过这种方式(DOM Level 2 events),我们可以附加无限个事件到同一个元素,唯一限制我们的就是客户端的内存和其它相关浏览器相关的性能了。
这种方式我们可以灵活地使用anonymous function、function reference或“闭包”:
<pre>
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
</pre>
另一个重要的addEventListener的特点是最后一个参数,用来控制事件监听器是如何来响应事件的传播机制的(也就是说是否启用capture)。当然,我用的是false在上例中,意思是不使用capture用bubble式,默认的方式,也是约95%的案例所用的处理方式。
但这个参数对于attachEvent()或元素内联事件inline events来说却并没有一个相应的参数来处理。
元素的内联事件Inline events
Ex:
(HTML onclick="" property and element.onclick)
大多数主流的浏览器支持内联事件Inline event中执行javascript代码,我们可以放置一个事件监听器event listener到元素的属性上,类似如下:
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
大多数有经验的开发者会尽量避开这种方式,但他确实能达到想要的效果;
因为他太简单粗暴直接。
在此处,你可以不用“闭包”和匿名函数anonymous functions(尽管从类别上来说这个处理器自身就是一个匿名函数),因为你能控制的作用域是有限制的。
另一种方法是:
element.onclick = function () { /*do stuff here */ };
这种方法其实是等价于上面的内联事件的,只不过内联javascript希望能够使得你能有更多的作用域方面的控制(因此,你可以编写一个JavaScript脚本,而不是只有HTML)而且能够使用匿名函数、函数引用和“闭包”。
不过,相比以上方式的简单直接而言他们最大的缺点就非常突出了,我们可以也仅仅只可以添加一个内联事件,因为内联事件是作为元素的特性/属性attribute/property来存储在元素element上的,也就是说,元素的属性是可以覆写的.
看下例:
<pre>
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
</pre>
我们点击element元素时,可以看到仅仅只有"Did stuff #2"生效,因为第二个值覆盖了第一个分配的值,而且,同时我们也覆盖了元素原生的内联HTML的onclick特性/属性property,具体参看: http://jsfiddle.net/jpgah/
哪一种更好?
这个问题关乎浏览器兼容性的需要以及我们自身的需要,是否我们真的需要附加多个事件到同一个元素上呢?是否我们的项目更具前瞻性,可以用更超前的方式?如果是attachEvent()和addEventListener()都可以考虑,如果不是,一个小小的内联元素inline event也能搞惦这个把戏。
不过jQuery和一些其它类似的javascript框架已经把这些问题打包成了通用的解决方案了,同样的代码用jQuery来实现就很简单了,而且所有的不同类型的浏览器都兼容:
$(element).on('click', function () { /* do stuff */ });
最后,不要试着用一种方式来做这个事情,我们可以小改动一下来照顾一下老版本的浏览器:
function addEvent(element, evnt, funct){
if (element.attachEvent)
return element.attachEvent('on'+evnt, funct);
else
return element.addEventListener(evnt, funct, false);
}
// example
addEvent(document.getElementById('myElement'),'click',function () { alert('hi!'); }
);