Both are correct, but none of them are "best" per se, and there may be a reason the developer chose to use both approaches.
(两种方法都是正确的,但是它们本身都不是“最佳”的,并且开发人员选择使用这两种方法可能是有原因的。)
Event Listeners (addEventListener and IE's attachEvent)
(事件监听器(addEventListener和IE的attachEvent))
Earlier versions of Internet Explorer implement javascript differently from pretty much every other browser.
(较早版本的Internet Explorer与几乎所有其他浏览器相比,实现javascript的方式有所不同。)
With versions less than 9, you use the attachEvent
[ doc ] method, like this:(在版本小于9的情况下,您可以使用attachEvent
[ doc ]方法,如下所示:)
element.attachEvent('onclick', function() { /* do stuff here*/ });
In most other browsers (including IE 9 and above), you use addEventListener
[ doc ], like this:
(在大多数其他浏览器(包括IE 9及更高版本)中,您可以使用addEventListener
[ doc ],如下所示:)
element.addEventListener('click', function() { /* do stuff here*/ }, false);
Using this approach ( DOM Level 2 events ), you can attach a theoretically unlimited number of events to any single element.
(使用这种方法( DOM 2级事件 ),您可以将理论上不受限制的事件数量附加到任何单个元素。)
The only practical limitation is client-side memory and other performance concerns, which are different for each browser.(唯一实际的限制是客户端内存和其他性能问题,这对于每个浏览器都是不同的。)
The examples above represent using an anonymous function[ doc ].
(上面的示例表示使用匿名函数[ doc ]。)
You can also add an event listener using a function reference[ doc ] or a closure[ doc ]:(您还可以使用函数引用[ doc ]或闭包[ doc ]添加事件侦听器:)
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
Another important feature of addEventListener
is the final parameter, which controls how the listener reacts to bubbling events[ doc ].
(的另一个重要特征addEventListener
是最后的参数,它控制如何监听到做出反应的事件冒泡[ DOC ]。)
I've been passing false in the examples, which is standard for probably 95% of use cases.(我在示例中传递了错误,这可能是95%用例的标准。)
There is no equivalent argument for attachEvent
, or when using inline events.(对于attachEvent
或使用内联事件时,没有等效的参数。)
Inline events (HTML onclick="" property and element.onclick)
(内联事件(HTML onclick =“”属性和element.onclick))
In all browsers that support javascript, you can put an event listener inline, meaning right in the HTML code.
(在所有支持javascript的浏览器中,您都可以内嵌事件监听器,这意味着HTML代码中的内容。)
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.(您不能在此处使用闭包或匿名函数(尽管处理程序本身是某种匿名函数),并且您对范围的控制受到限制。)
The other method you mention:
(您提到的另一种方法:)
element.onclick = function () { /*do stuff here */ };
... 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.
(除了可以更好地控制范围(因为您正在编写脚本而不是HTML),并且可以使用匿名函数,函数引用和/或闭包之外,...等效于内联javascript。)
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.(内联事件存储为element [ doc ]的属性/属性,这意味着可以覆盖它。)
Using the example <a>
from the HTML above:
(使用上面HTML中的示例<a>
:)
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
... 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.
(...当您单击该元素时,您只会看到“第2件东西”-您用第二个值覆盖了onclick
属性的第一个分配值,也覆盖了原始的内联HTML onclick
属性。)
Check it out here: http://jsfiddle.net/jpgah/ .(在此处查看: http : //jsfiddle.net/jpgah/ 。)
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.(可能有特定的用例,但是如果您不是100%确信拥有该用例,那么您就不要使用内联事件。)
Modern Javascript (Angular and the like)
(现代Javascript(Angular等))
Since this answer was originally posted, javascript frameworks like Angular have become far more popular.
(自从这个答案最初发布以来,像Angular这样的javascript框架已经变得越来越流行。)
You will see code like this in an Angular template:(您将在Angular模板中看到如下代码:)
<button (click)="doSomething()">Do Something</button>
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.(您应该了解具体细节,但是,如果您的现代JS框架最佳实践涉及在模板中编写此类代码,那么您就不会觉得自己在使用内联事件-并不是。)
Which is Best?
(哪个最好?)
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.(attachEvent和addEventListener是必需的。)
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.(您有机会必须转向基于JS的事件侦听器,因此您最好从那里开始。)
Don't use inline events.(不要使用内联事件。)
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.
(jQuery和其他JavaScript框架在通用模型中封装了DOM 2级事件的不同浏览器实现,因此您可以编写跨浏览器兼容的代码,而不必担心IE作为反叛者的历史。)
Same code with jQuery, all cross-browser and ready to rock:(与jQuery相同的代码,所有的跨浏览器都可以使用:)
$(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'),