addEventListener和onclick有什么区别?

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

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


当前回答

在我的Visual Studio代码中,addEventListener对事件有真实的智能感知

但onclick没有,只有假的

其他回答

addEventListener允许您设置多个处理程序,但在IE8或更低版本中不支持。

IE确实有attachEvent,但它并不完全相同。

你也应该考虑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”…读一读吧!

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

根据MDN,差异如下:

addEventListener:

EventTarget.addEventListener()方法添加指定的 对象的事件侦听器列表中的 在调用它的EventTarget上指定的事件类型。的 事件目标可以是文档中的一个元素,文档本身,一个 窗口或任何其他支持事件的对象(例如 XMLHttpRequest)。

onclick:

属性上的单击事件处理程序代码 当前元素。当使用click事件触发操作时,也是如此 考虑将相同的操作添加到keydown事件,以允许 不使用鼠标或触摸的人使用相同的动作 屏幕上。语法元素。onclick = functionRef;where functionRef是a 函数——通常是在别处声明的函数名或函数名 表达式。详见“JavaScript指南:函数”。

在使用中也有语法差异,你可以在下面的代码中看到: addEventListener:

// Function to change the content of t2
function modifyText() {
  var t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "three") {
    t2.firstChild.nodeValue = "two";
  } else {
    t2.firstChild.nodeValue = "three";
  }
}

// add event listener to table
var el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);

onclick:

function initElement() {
    var p = document.getElementById("foo");
    // NOTE: showAlert(); or showAlert(param); will NOT work here.
    // Must be a reference to a function name, not a function call.
    p.onclick = showAlert;
};

function showAlert(event) {
    alert("onclick Event detected!");
}

一个元素对每种事件类型只能有一个事件处理程序,但可以有多个事件监听器。


那么,它的实际情况如何呢?

只有最后分配的事件处理程序才会运行:

const button = document.querySelector(".btn")
button.onclick = () => {
  console.log("Hello World");
};
button.onclick = () => {
  console.log("How are you?");
};
button.click() // "How are you?" 

所有事件监听器将被触发:

const button = document.querySelector(".btn")
button.addEventListener("click", event => {
  console.log("Hello World");
})
button.addEventListener("click", event => {
  console.log("How are you?");
})
button.click() 
// "Hello World"
// "How are you?"

IE注:attachEvent不再支持。从IE 11开始,使用addEventListener: docs。