addEventListener
和onclick
有什么区别?
var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);
上面的代码一起驻留在单独的.js文件中,并且它们都可以正常工作。
最佳答案
两种方法都是正确的,但是它们本身都不是“最佳”的,并且开发人员选择使用这两种方法可能是有原因的。
事件侦听器(addEventListener和IE的attachEvent)
较早版本的Internet Explorer与几乎所有其他浏览器相比,实现javascript的方式有所不同。在版本小于9的情况下,您可以使用attachEvent
[doc]方法,如下所示:
element.attachEvent('onclick', function() { /* do stuff here*/ });
在大多数其他浏览器(包括IE 9和更高版本)中,您使用
addEventListener
[doc],如下所示:element.addEventListener('click', function() { /* do stuff here*/ }, false);
使用这种方法(DOM Level 2 events),您可以将理论上不受限制的事件数量附加到任何单个元素。唯一实际的限制是客户端内存和其他性能问题,这对于每个浏览器都是不同的。
上面的示例表示使用匿名函数[doc]。您还可以使用函数引用[doc]或闭包[doc]添加事件侦听器:
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
addEventListener
的另一个重要功能是final参数,该参数控制侦听器对冒泡事件的 react [doc]。我在示例中传递了错误,这可能是95%用例的标准。 attachEvent
或使用内联事件时没有等效的参数。内联事件(HTML onclick =“”属性和element.onclick)
在所有支持javascript的浏览器中,您都可以内嵌事件监听器,这意味着HTML代码中的内容。您可能已经看到了:
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
大多数有经验的开发人员都避免使用这种方法,但是确实可以完成工作。简单而直接。您不能在此处使用闭包或匿名函数(尽管处理程序本身是某种匿名函数),并且您对范围的控制受到限制。
您提到的另一种方法:
element.onclick = function () { /*do stuff here */ };
除了可以更好地控制范围(因为您正在编写脚本而不是HTML),并且可以使用匿名函数,函数引用和/或闭包之外,...等效于内联javascript。
内联事件的主要缺点是,与上述事件侦听器不同,您可能只分配了一个内联事件。内联事件存储为元素[doc]的属性/属性,意味着可以覆盖它。
使用上面HTML中的
<a>
示例:var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
...当您单击该元素时,您只需要 看到“Did stuff#2”-您用第二个值覆盖了
onclick
属性的第一个分配值,并且也覆盖了原始的内联HTML onclick
属性。在此处检查:http://jsfiddle.net/jpgah/。广义上讲,不使用内联事件。可能有一些特定的用例,但是如果您不是100%确信拥有该用例,那么您就不要也不应使用内联事件。
现代Javascript(Angular等)
自从最初发布此答案以来,像Angular这样的javascript框架已经变得越来越流行。您将在Angular模板中看到如下代码:
<button (click)="doSomething()">Do Something</button>
这看起来像一个内联事件,但事实并非如此。此类模板将被转换为更复杂的代码,该代码在后台使用事件侦听器。我在此处编写的有关事件的所有内容仍然适用,但是您至少要从一层坚硬的泥泞中解脱出来。您应该了解具体细节,但是如果您的现代JS框架最佳实践涉及在模板中编写此类代码,那么您就不会觉得自己在使用内联事件-并不是。
最好?
问题是浏览器的兼容性和必要性。您是否需要将多个事件附加到一个元素?你将来会吗?很有可能,你会的。 attachEvent和addEventListener是必需的。如果不是这样,则内联事件似乎可以解决问题,但是为将来做准备更好,尽管看起来似乎不太可能,但至少可以预见。您有机会必须转向基于JS的事件侦听器,因此您最好从那里开始。不要使用内联事件。
jQuery和其他JavaScript框架在通用模型中封装了DOM 2事件的不同浏览器实现,因此您可以编写跨浏览器兼容的代码,而不必担心IE作为反叛者的历史。与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!'); }
);
试试看:http://jsfiddle.net/bmArj/
考虑到所有这些因素,除非您正在查看的脚本以其他方式考虑了浏览器的差异(问题中未显示的代码),否则使用
addEventListener
的部分在低于9的IE版本中将不起作用。文档和相关阅读
关于javascript - addEventListener与onclick,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6902033/