addEventListener和onclick有什么区别?

var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);

上面的代码一起驻留在一个单独的.js文件中,它们都可以完美地工作。


当前回答

如果你有另外两个函数,你可以看到区别:

var h = document.getElementById('a');
h.onclick = doThing_1;
h.onclick = doThing_2;

h.addEventListener('click', doThing_3);
h.addEventListener('click', doThing_4);

函数2、3和4可以工作,但函数1不行。这是因为addEventListener不会覆盖现有的事件处理程序,而onclick会覆盖任何现有的onclick = fn事件处理程序。

当然,另一个重要的区别是onclick总是可以工作,而addEventListener在版本9之前的ie中不能工作。你可以在IE <9中使用类似的attachEvent(语法略有不同)。

其他回答

虽然onclick可以在所有浏览器中工作,但addEventListener不能在旧版本的Internet Explorer中工作,后者使用attachEvent代替。

onclick的缺点是只能有一个事件处理程序,而其他两个将触发所有注册的回调。

Javascript倾向于把所有东西都混合到对象中,这可能会让人困惑。这就是JavaScript的方式。

本质上,onclick是一个HTML属性。相反,addEventListener是DOM对象上表示HTML元素的方法。

在JavaScript对象中,方法只是一个属性,它有一个函数作为值,并且对它所附加的对象起作用(例如使用这个)。

在JavaScript中,DOM表示的HTML元素将其属性映射到其属性上。

这就是人们感到困惑的地方,因为JavaScript将所有东西都融合到一个单独的容器或名称空间中,没有任何间接层。

在一个正常的OO布局中(它至少合并了属性/方法的命名空间),你可能会有这样的东西:

domElement.addEventListener // Object(Method)
domElement.attributes.onload // Object(Property(Object(Property(String))))

有一些变化,比如它可以为onload使用getter/setter,或者为属性使用HashMap,但最终这就是它的外观。JavaScript消除了这一间接层,期望知道什么是什么。它将domElement和属性合并在一起。

为了限制兼容性,最好使用addEventListener。由于其他答案谈论的是这方面的差异,而不是基本的方案差异,我将放弃它。本质上,在理想的情况下,你只能从HTML中使用on*,但在更理想的情况下,你不应该从HTML中做任何类似的事情。

为什么它在今天占主导地位?这样写起来更快,更容易学习,而且更容易工作。

HTML中onload的全部意义在于首先提供对addEventListener方法或功能的访问。通过在JS中使用它,当你可以直接应用它时,你会通过HTML。

假设你可以创建自己的属性:

$('[myclick]').each(function(i, v) {
     v.addEventListener('click', function() {
         eval(v.myclick); // eval($(v).attr('myclick'));
     });
});

JS所做的与此有点不同。

你可以将它等同于(对于创建的每个元素):

element.addEventListener('click', function() {
    switch(typeof element.onclick) {
          case 'string':eval(element.onclick);break;
          case 'function':element.onclick();break;
     }
});

实际的实现细节可能会有所不同,有一系列微妙的变化,使两者在某些情况下略有不同,但这是它的要点。

这可以说是一种兼容性hack,您可以将一个函数固定到一个on属性,因为默认属性都是字符串。

我想Chris Baker在一个很好的答案中总结了它,但我想添加到addEventListener()中,你也可以使用options参数,它可以让你更好地控制你的事件。例如,如果你只想运行你的事件一次,那么你可以在添加事件时使用{once: true}作为一个选项参数,只调用它一次。

    function greet() {
    console.log("Hello");
    }   
    document.querySelector("button").addEventListener('click', greet, { once: true })

上面的函数只打印“Hello”一次。 此外,如果你想清理你的事件,那么还有removeEventListener()选项。虽然使用addEventListener()有优点,但如果您的目标受众使用Internet Explorer,则此方法可能并不适用于所有情况,您仍然应该小心。你也可以在MDN上读到addEventListener,他们对如何使用它们给出了很好的解释。

简介:

addEventListener可以添加多个事件,而onclick则不能这样做。 onclick可以作为HTML属性添加,而addEventListener只能添加在<script>元素中。 addEventListener可以接受第三个参数,该参数可以停止事件传播。

两者都可用于处理事件。然而,addEventListener应该是首选的选择,因为它可以做onclick做的所有事情,甚至更多。不要使用内联onclick作为HTML属性,因为这会混淆javascript和HTML,这是一个坏的做法。它使代码更难维护。

一个细节还没有被注意到:现代桌面浏览器将不同的按钮按下视为AddEventListener的“单击”(默认为“单击”和“onclick”)。

在Chrome 42和IE11上,onclick和AddEventListener都单击左边的fire和中间的click。 在Firefox 38上,onclick只在左键点击时触发,但AddEventListener点击在左、中、右击时触发。

此外,当使用滚动游标时,中键点击行为在浏览器中非常不一致:

在Firefox上,中键单击事件总是会触发。 在Chrome浏览器上,如果中间点击打开或关闭滚动光标,它们不会触发。 在IE上,它们会在滚动光标关闭时触发,但不会在打开时触发。

同样值得注意的是,任何键盘可选择的HTML元素(如input)的“click”事件也会在元素被选中时触发空格或enter。