addEventListener 与 onclick [英] addEventListener vs onclick

查看:28
本文介绍了addEventListener 与 onclick的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

addEventListeneronclick 有什么区别?

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

上面的代码共同存在于一个单独的 .js 文件中,它们都可以完美运行.

The code above resides together in a separate .js file, and they both work perfectly.

推荐答案

两者都是正确的,但它们本身都不是最好的",开发人员选择使用这两种方法可能是有原因的.

Both are correct, but none of them are "best" per se, and there may be a reason the developer chose to use both approaches.

事件监听器(addEventListener 和 IE 的 attachEvent)

早期版本的 Internet Explorer 实现 javascript 的方式与几乎所有其他浏览器不同.对于低于 9 的版本,您可以使用 attachEvent[doc] 方法,像这样:

Earlier versions of Internet Explorer implement javascript differently from pretty much every other browser. With versions less than 9, you use the attachEvent[doc] method, like this:

element.attachEvent('onclick', function() { /* do stuff here*/ });

在大多数其他浏览器(包括 IE 9 及更高版本)中,您使用 addEventListener[doc],像这样:

In most other browsers (including IE 9 and above), you use addEventListener[doc], like this:

element.addEventListener('click', function() { /* do stuff here*/ }, false);

使用这种方法(DOM Level 2 events),您可以附加一个理论上无限的任何单个元素的事件数.唯一的实际限制是客户端内存和其他性能问题,每个浏览器都不同.

Using this approach (DOM Level 2 events), you can attach a theoretically unlimited number of events to any single element. The only practical limitation is client-side memory and other performance concerns, which are different for each browser.

以上示例表示使用匿名函数[doc].您还可以使用函数参考[doc] 或闭包[doc]:

The examples above represent using an anonymous function[doc]. You can also add an event listener using a function reference[doc] or a closure[doc]:

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

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

addEventListener 的另一个重要特性是最后一个参数,它控制监听器对冒泡事件的反应[doc].我一直在示例中传递 false,这对于大约 95% 的用例来说是标准的.attachEvent 或使用内联事件时没有等效参数.

Another important feature of addEventListener is the final parameter, which controls how the listener reacts to bubbling events[doc]. I've been passing false in the examples, which is standard for probably 95% of use cases. There is no equivalent argument for attachEvent, or when using inline events.

内联事件(HTML onclick="" 属性和 element.onclick)

在所有支持 javascript 的浏览器中,您可以将事件侦听器内联,这意味着就在 HTML 代码中.您可能已经看过这个:

In all browsers that support javascript, you can put an event listener inline, meaning right in the HTML code. You've probably seen this:

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

大多数有经验的开发人员都避免使用这种方法,但它确实可以完成工作;它简单而直接.您不能在此处使用闭包或匿名函数(尽管处理程序本身是某种匿名函数),并且您对范围的控制是有限的.

Most experienced developers shun this method, but it does get the job done; it is simple and direct. You may not use closures or anonymous functions here (though the handler itself is an anonymous function of sorts), and your control of scope is limited.

你提到的另一种方法:

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

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

... is the equivalent of inline javascript except that you have more control of the scope (since you're writing a script rather than HTML) and can use anonymous functions, function references, and/or closures.

内联事件的显着缺点是与上述事件侦听器不同,您可能只分配了一个内联事件.内联事件存储为元素的属性/属性[doc],表示可以覆盖.

The significant drawback with inline events is that unlike event listeners described above, you may only have one inline event assigned. Inline events are stored as an attribute/property of the element[doc], meaning that it can be overwritten.

使用上面 HTML 中的示例 :

Using the example <a> from the HTML above:

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/.

... when you clicked the element, you'd only see "Did stuff #2" - you overwrote the first assigned of the onclick property with the second value, and you overwrote the original inline HTML onclick property too. Check it out here: http://jsfiddle.net/jpgah/.

概括地说,不要使用内联事件.它可能有特定的用例,但如果您不能 100% 确定您有该用例,那么您不会也不应该使用内联事件.

Broadly speaking, do not use inline events. There may be specific use cases for it, but if you are not 100% sure you have that use case, then you do not and should not use inline events.

现代 Javascript(Angular 等)

自从这个答案最初发布以来,像 Angular 这样的 javascript 框架变得越来越流行.您将在 Angular 模板中看到这样的代码:

Since this answer was originally posted, javascript frameworks like Angular have become far more popular. You will see code like this in an Angular template:

<button (click)="doSomething()">Do Something</button>

这看起来像一个内联事件,但它不是.这种类型的模板将被转换成更复杂的代码,在幕后使用事件侦听器.我在这里写的关于事件的所有内容仍然适用,但你已经从本质上被移除了至少一层.您应该了解具体细节,但如果您的现代 JS 框架最佳实践涉及在模板中编写此类代码,请不要觉得您在使用内联事件——您不是.

This looks like an inline event, but it isn't. This type of template will be transpiled into more complex code which uses event listeners behind the scenes. Everything I've written about events here still applies, but you are removed from the nitty gritty by at least one layer. You should understand the nuts and bolts, but if your modern JS framework best practices involve writing this kind of code in a template, don't feel like you're using an inline event -- you aren't.

哪个最好?

问题是浏览器兼容性和必要性的问题.您是否需要将多个事件附加到一个元素?将来你会吗?很有可能,你会的.attachEvent 和 addEventListener 是必需的.如果没有,内联事件似乎可以解决问题,但您最好为未来做好准备,尽管这似乎不太可能,但至少是可以预测的.您有可能不得不转向基于 JS 的事件侦听器,因此您不妨从那里开始.不要使用内联事件.

The question is a matter of browser compatibility and necessity. Do you need to attach more than one event to an element? Will you in the future? Odds are, you will. attachEvent and addEventListener are necessary. If not, an inline event may seem like they'd do the trick, but you're much better served preparing for a future that, though it may seem unlikely, is predictable at least. There is a chance you'll have to move to JS-based event listeners, so you may as well just start there. Don't use inline events.

jQuery 和其他 javascript 框架将 DOM 级别 2 事件的不同浏览器实现封装在通用模型中,因此您可以编写跨浏览器兼容的代码,而不必担心 IE 的历史叛逆.与 jQuery 相同的代码,所有跨浏览器并准备好摇滚:

jQuery and other javascript frameworks encapsulate the different browser implementations of DOM level 2 events in generic models so you can write cross-browser compliant code without having to worry about IE's history as a rebel. Same code with jQuery, all cross-browser and ready to rock:

$(element).on('click', function () { /* do stuff */ });

不过,不要用完只为这件事准备一个框架.您可以轻松推出自己的小实用程序来处理较旧的浏览器:

Don't run out and get a framework just for this one thing, though. You can easily roll your own little utility to take care of the older browsers:

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.

Taking all of that into consideration, unless the script you're looking at took the browser differences into account some other way (in code not shown in your question), the part using addEventListener would not work in IE versions less than 9.

文档和相关阅读

这篇关于addEventListener 与 onclick的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆