addEventListener和onclick有什么区别?

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

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


当前回答

你也应该考虑eventdelegate ! 因此,我更喜欢addEventListener,最重要的是小心谨慎地使用它!

事实:

eventlistener是沉重的....(客户端内存分配) 事件在与DOM的关系中传播IN,然后再次传播OUT 树。也被称为涓滴式和冒泡式,读一读 以防你不知道。

想象一个简单的例子: 一个简单的按钮内部div内部主体… 如果你点击按钮,一个事件将无论如何 滴入到BUTTON,然后再OUT,像这样:

window-document-div-button-div-document-window

在浏览器后台(比如JS引擎的软件外围),浏览器只能对点击做出反应,如果它检查了每一次点击的目标位置。

为了确保每个可能的事件监听器都被触发,它必须从文档级别一直发送“点击事件信号”到元素中。然后再回来。 这个行为可以通过附加eventlistener来使用,例如:

document.getElementById("exampleID").addEventListener("click",(event) => {doThis}, true/false);

请注意,作为addEventListener方法最后一个参数的true/false控制了何时识别事件的行为——何时流入或何时流出。

TRUE表示事件在传入时被识别 FALSE表示事件在冒泡输出的过程中被识别

实现以下2个有用的概念,使用上述方法处理问题也会更加直观:

You can also use event.stopPropagation() within the function (example ref. "doThis") to prevents further propagation of the current event in the capturing and bubbling phases. It does not, however, prevent any default behaviors from occurring; for instance, clicks on links are still processed. If you want to stop those behaviors, you could use event.preventDefault() within the function (example ref. "doThis"). With that you could for example tell the Browser that if the event does not get explicitly handled, its default action should not be taken as it normally would be.

还需要再次注意这里的参考:addEventListener方法的最后一个参数(true/false)也控制了“. stoppropagation()”的最终效果在哪个阶段生效(涓滴为true或冒头为false)。 所以…如果你将一个带有TRUE标志的EventListener应用到一个元素,并将其与.stopPropagation()方法结合起来,事件甚至不会通过元素的潜在内部子元素

总结一下: 如果你在HTML中使用onClick变体…对我来说有两个缺点:

与addEventListener,你可以附加多个onClick事件到相同的,分别是一个单一的元素,但这是不可能使用onClick(至少这是我坚信到目前为止,如果我错了,请纠正我)。 以下方面也确实值得注意……特别是代码维护部分(到目前为止还没有详细说明):

In regards to event delegation, it really boils down to this. If some other JavaScript code needs to respond to a click event, using addEventListener ensures you both can respond to it. If you both try using onclick, then one stomps on the other. You both can't respond if you want an onclick on the same element. Furthermore, you want to keep your behavior as separate as you can from the HTML in case you need to change it later. It would suck to have 50 HTML files to update instead of one JavaScript file. (credit to Greg Burghardt, addEventListener vs onclick with regards to event delegation )

这也被称为“Unobtrusive JavaScript”…读一读吧!

其他回答

也可以通过对侦听器进行原型化(如果我们有对它的引用,而且它不是匿名函数)来扩展侦听器,或者使onclick调用成为对函数库的调用(函数调用其他函数)。

如:

elm.onclick = myFunctionList;
function myFunctionList(){
    myFunc1();
    myFunc2();
}

这意味着我们永远不需要改变onclick调用,只需要改变myFunctionList()函数来做任何我们想做的事情,但这让我们无法控制冒泡/捕获阶段,所以应该避免在新浏览器中使用。

let element = document.queryselector('id or classname'); 
element.addeventlistiner('click',()=>{
  do work
})

<button onclick="click()">click</click>`
function click(){
  do work
};

元素。Onclick = function() {/* do stuff */} 元素。addEventListener('click', function(){/* do stuff */},false);

它们显然做同样的事情:监听click事件并执行回调函数。然而,它们是不相等的。如果你需要在两者之间做出选择,这可以帮助你弄清楚哪一个最适合你。

主要的区别是onclick只是一个属性,像所有对象属性一样,如果你写了多次,它将被覆盖。而使用addEventListener(),我们可以简单地将事件处理程序绑定到元素,并且可以在每次需要时调用它,而不用担心任何重写的属性。 例子如下,

试试吧:https://jsfiddle.net/fjets5z4/5/

首先,我想继续使用onclick,因为它更短,看起来更简单,事实上也是如此。但我不建议再使用它了。这就像使用内联JavaScript一样。使用内联JavaScript之类的东西现在是非常不鼓励的(内联CSS也是不鼓励的,但这是另一个话题)。

然而,addEventListener()函数尽管是标准的,但在旧的浏览器(Internet Explorer低于版本9)中不能工作,这是另一个很大的区别。如果您需要支持这些古老的浏览器,您应该遵循onclick方式。但是你也可以使用jQuery(或它的替代品之一):它基本上简化了你的工作,减少了浏览器之间的差异,因此可以节省你很多时间。

var clickEvent = document.getElementByID("onclick-eg");
var EventListener = document.getElementByID("addEventListener-eg");

clickEvent.onclick = function(){
    window.alert("1 is not called")
}
clickEvent.onclick = function(){
    window.alert("1 is not called, 2 is called")
}

EventListener.addEventListener("click",function(){
    window.alert("1 is called")
})
EventListener.addEventListener("click",function(){
    window.alert("2 is also called")
})

使用内联处理程序与内容安全策略不兼容,因此addEventListener方法从这个角度来看更安全。当然,您可以使用unsafe-inline来启用内联处理程序,但是,顾名思义,它并不安全,因为它会带来CSP阻止的大量JavaScript漏洞。

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属性,因为默认属性都是字符串。