addEventListener vs onclick

addEventListeneronclick什么区别?

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事件),您可以将理论上无限数量的事件附加到任何单个元素。 唯一的实际限制是客户端内存和其他性能问题,这对每个浏览器都是不同的。

上面的例子表示使用匿名函数[doc]。 您还可以使用函数reference [doc]或闭包[doc]添加事件侦听器:

var myFunctionReference = function() { /* do stuff here*/ }

element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);

addEventListener另一个重要特性是最终参数,它控制侦听器如何对冒泡事件做出反应[doc]。 我在例子中传递了错误,这可能是95%的用例的标准。 attachEvent没有等价的参数,或者使用内联事件时。

内联事件(HTML onclick =“”property and element.onclick)

在支持javascript的所有浏览器中,您可以将事件侦听器内联,即在HTML代码中正确表示。 你可能已经看到了这个:

<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>

大多数有经验的开发人员避开这种方法,但它确实完成了工作; 它简单直接。 你不能在这里使用闭包或匿名函数(虽然处理程序本身是一个匿名函数),你对范围的控制是有限的。

你提到的另一种方法:

element.onclick = function () { /*do stuff here */ };

...相当于内联javascript,不同之处在于您可以更好地控制范围(因为您正在编写脚本而不是HTML),并且可以使用匿名函数,函数引用和/或闭包。

内联事件的一个明显缺点是,与上述事件监听器不同,您可能只分配了一个内联事件。 内联事件存储为元素[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/。

哪个最好?

问题在于浏览器的兼容性和必要性。 您目前是否需要为一个元素附加多个事件? 你会在未来吗? 赔率是,你会的。 attachEvent和addEventListener是必需的。 如果不是的话,一个内联事件将会诀窍。

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的部分在IE版本少于9的情况下将不起作用。

文件和相关阅读

  • W3 HTML规范,元素事件处理程序属性
  • MDN上的element.addEventListener
  • MSDN上的element.attachEvent
  • Jquery.on
  • quirksmode博客“事件简介”
  • 在谷歌C​​DN托管的JavaScript库

  • 你可以看到,如果你有另外几个功能的区别:

    var h = document.getElementById('a');
    h.onclick = donothing1;
    h.onclick = donothing2;
    
    h.addEventListener('click', donothing3);
    h.addEventListener('click', donothing4);
    

    功能2,3和4工作,但1不工作。 这是因为addEventListener不覆盖现有的事件处理程序,而onclick覆盖任何现有的onclick = fn事件处理程序。

    当然,另一个显着差异是onclick将始终工作,而addEventListener在版本9之前的Internet Explorer中不起作用。您可以在IE <9中使用类似的attachEvent (语法略有不同)。


    在这个答案中,我将描述定义DOM事件处理程序的三种方法。

    element.addEventListener()

    代码示例:

    const element = document.querySelector('a');
    element.addEventListener('click', event => event.preventDefault(), true);
    <a href="//google.com">Try clicking this link.</a>
    链接地址: http://www.djcxy.com/p/51949.html

    上一篇: addEventListener vs onclick

    下一篇: fastest way to wake up a thread without using condition variable