addEventListener和onclick有什么区别?

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

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


当前回答

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

其他回答

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

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

element.addEventListener()

代码示例:

const element = document.querySelector('a'); 元素。addEventListener('click', event => event. preventdefault (), true); <a href="//google.com">试着点击这个链接

addeventlistener()有多个优点:

Allows you to register unlimited events handlers and remove them with element.removeEventListener(). Has useCapture parameter, which indicates whether you'd like to handle event in its capturing or bubbling phase. See: Unable to understand useCapture attribute in addEventListener. Cares about semantics. Basically, it makes registering event handlers more explicit. For a beginner, a function call makes it obvious that something happens, whereas assigning event to some property of DOM element is at least not intuitive. Allows you to separate document structure (HTML) and logic (JavaScript). In tiny web applications it may not seem to matter, but it does matter with any bigger project. It's way much easier to maintain a project which separates structure and logic than a project which doesn't. Eliminates confusion with correct event names. Due to using inline event listeners or assigning event listeners to .onevent properties of DOM elements, lots of inexperienced JavaScript programmers thinks that the event name is for example onclick or onload. on is not a part of event name. Correct event names are click and load, and that's how event names are passed to .addEventListener(). Works in almost all browser. If you still have to support IE <= 8, you can use a polyfill from MDN.

元素。Onevent = function(){}(例如onclick, onload)

代码示例:

const element = document.querySelector('a'); 元素。onclick = event => event. preventdefault (); <a href="//google.com">试着点击这个链接

这是在DOM 0中注册事件处理程序的一种方法。现在不鼓励这样做,因为:

Allows you to register only one event handler. Also removing the assigned handler is not intuitive, because to remove event handler assigned using this method, you have to revert onevent property back to its initial state (i.e. null). Doesn't respond to errors appropriately. For example, if you by mistake assign a string to window.onload, for example: window.onload = "test";, it won't throw any errors. Your code wouldn't work and it would be really hard to find out why. .addEventListener() however, would throw error (at least in Firefox): TypeError: Argument 2 of EventTarget.addEventListener is not an object. Doesn't provide a way to choose if you want to handle event in its capturing or bubbling phase.

内联事件处理程序(onevent HTML属性)

代码示例:

<a href="//google.com" onclick="event.preventDefault();>试着点击这个链接

类似于element。Onevent,现在不鼓励了。除了那个元素的问题。Onevent有,它:

Is a potential security issue, because it makes XSS much more harmful. Nowadays websites should send proper Content-Security-Policy HTTP header to block inline scripts and allow external scripts only from trusted domains. See How does Content Security Policy work? Doesn't separate document structure and logic. If you generate your page with a server-side script, and for example you generate a hundred links, each with the same inline event handler, your code would be much longer than if the event handler was defined only once. That means the client would have to download more content, and in result your website would be slower.

另请参阅

EventTarget.addEventListener()文档(MDN) EventTarget.removeEventListener()文档(MDN) onclick vs addEventListener Dom-events标记wiki

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


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

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

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。

“this”关键字在JavasSript中引用的上下文是不同的。

请看下面的代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>

</head>
<body>
    <input id="btnSubmit" type="button" value="Submit" />
    <script>
        function disable() {
            this.disabled = true;
        }
        var btnSubmit = document.getElementById('btnSubmit');
        btnSubmit.onclick = disable();
        //btnSubmit.addEventListener('click', disable, false);
    </script>
</body>
</html>

它的功能非常简单。当您点击该按钮时,该按钮将自动禁用。

首先,当您尝试以这种方式按钮连接事件时。Onclick = function(), 点击按钮会触发Onclick事件,但是,按钮不会被禁用,因为按钮之间没有显式的绑定。Onclick和Onclick事件处理器。如果你调试看到'this'对象,你可以看到它指向'window'对象。

其次,如果你评论btnSubmit。Onclick =禁用();和取消 / / btnSubmit。addEventListener('点击',禁用,false);您可以看到按钮是禁用的,因为通过这种方式,按钮之间有显式绑定。点击事件和点击事件处理程序。如果你调试为禁用功能,你可以看到“this”指的是按钮控件而不是窗口。

这是我不喜欢JavaScript不一致的地方。 顺便说一句,如果你使用jQuery($('#btnSubmit')。On ('click', disable);),它使用显式绑定。

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

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