Beide sind korrekt, aber keiner von ihnen ist per se "am besten", und es kann einen Grund geben, warum der Entwickler beide Ansätze gewählt hat.
Ereignis-Listener (addEventListener und IE's attachEvent)
Frühere Versionen von Internet Explorer implementieren Javascript anders als so ziemlich jeder andere Browser. Bei Versionen unter 9 verwenden Sie die attachEvent
[ doc ] -Methode wie folgt:
element.attachEvent('onclick', function() { /* do stuff here*/ });
In den meisten anderen Browsern (einschließlich IE 9 und höher) verwenden Sie addEventListener
[ doc ] wie folgt:
element.addEventListener('click', function() { /* do stuff here*/ }, false);
Mit diesem Ansatz ( DOM Level 2-Ereignisse ) können Sie jedem einzelnen Element eine theoretisch unbegrenzte Anzahl von Ereignissen zuordnen. Die einzige praktische Einschränkung ist der clientseitige Speicher und andere Leistungsprobleme, die für jeden Browser unterschiedlich sind.
Die obigen Beispiele zeigen die Verwendung einer anonymen Funktion [ doc ]. Sie können einen Ereignis-Listener auch mithilfe einer Funktionsreferenz [ doc ] oder eines Abschlusses [ doc ] hinzufügen :
var myFunctionReference = function() { /* do stuff here*/ }
element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);
Ein weiteres wichtiges Merkmal von addEventListener
ist der letzte Parameter, der steuert, wie der Listener auf sprudelnde Ereignisse reagiert [ doc ]. Ich habe in den Beispielen false übergeben, was für wahrscheinlich 95% der Anwendungsfälle Standard ist. Es gibt kein gleichwertiges Argument für attachEvent
oder bei Verwendung von Inline-Ereignissen.
Inline-Ereignisse (HTML onclick = "" property und element.onclick)
In allen Browsern, die Javascript unterstützen, können Sie einen Ereignis-Listener inline setzen, dh direkt im HTML-Code. Sie haben wahrscheinlich Folgendes gesehen:
<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>
Die meisten erfahrenen Entwickler meiden diese Methode, aber sie erledigt den Job. es ist einfach und direkt. Sie dürfen hier keine Schließungen oder anonymen Funktionen verwenden (obwohl der Handler selbst eine Art anonyme Funktion ist), und Ihre Kontrolle über den Umfang ist begrenzt.
Die andere Methode, die Sie erwähnen:
element.onclick = function () { /*do stuff here */ };
... entspricht Inline-Javascript, außer dass Sie mehr Kontrolle über den Bereich haben (da Sie ein Skript anstelle von HTML schreiben) und anonyme Funktionen, Funktionsreferenzen und / oder Abschlüsse verwenden können.
Der wesentliche Nachteil bei Inline-Ereignissen besteht darin, dass im Gegensatz zu den oben beschriebenen Ereignis-Listenern möglicherweise nur ein Inline-Ereignis zugewiesen ist. Inline-Ereignisse werden als Attribut / Eigenschaft des Elements [ doc ] gespeichert , was bedeutet, dass es überschrieben werden kann.
Verwenden Sie das Beispiel <a>
aus dem obigen HTML:
var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };
... wenn Sie auf das Element geklickt haben, wird nur "Did stuff # 2" angezeigt. Sie haben die erste zugewiesene onclick
Eigenschaft mit dem zweiten Wert überschrieben und auch die ursprüngliche Inline-HTML- onclick
Eigenschaft. Überprüfen Sie es hier: http://jsfiddle.net/jpgah/ .
Grob gesagt, verwenden Sie keine Inline - Events . Es kann bestimmte Anwendungsfälle dafür geben, aber wenn Sie nicht 100% sicher sind, dass Sie diesen Anwendungsfall haben, verwenden Sie keine Inline-Ereignisse und sollten diese auch nicht verwenden.
Modernes Javascript (Angular und dergleichen)
Seit diese Antwort ursprünglich veröffentlicht wurde, sind Javascript-Frameworks wie Angular weitaus beliebter geworden. Sie sehen Code wie diesen in einer Angular-Vorlage:
<button (click)="doSomething()">Do Something</button>
Dies sieht aus wie ein Inline-Ereignis, ist es aber nicht. Diese Art von Vorlage wird in komplexeren Code umgewandelt, der Ereignis-Listener hinter den Kulissen verwendet. Alles, was ich hier über Ereignisse geschrieben habe, gilt immer noch, aber Sie werden durch mindestens eine Ebene aus dem Kern entfernt. Sie sollten die Grundlagen verstehen, aber wenn Ihre modernen Best Practices für JS-Frameworks das Schreiben dieser Art von Code in eine Vorlage beinhalten, haben Sie nicht das Gefühl, dass Sie ein Inline-Ereignis verwenden - das sind Sie nicht.
Welches das Beste ist?
Die Frage ist eine Frage der Browserkompatibilität und der Notwendigkeit. Müssen Sie einem Element mehr als ein Ereignis hinzufügen? Wirst du in der Zukunft? Die Chancen stehen gut, Sie werden. attachEvent und addEventListener sind erforderlich. Wenn nicht, scheint ein Inline-Ereignis den Trick zu tun, aber Sie sollten sich besser auf eine Zukunft vorbereiten, die, obwohl dies unwahrscheinlich erscheint, zumindest vorhersehbar ist. Es besteht die Möglichkeit, dass Sie zu JS-basierten Ereignis-Listenern wechseln müssen. Sie können also auch einfach dort beginnen. Verwenden Sie keine Inline-Ereignisse.
jQuery und andere Javascript-Frameworks kapseln die verschiedenen Browser-Implementierungen von DOM Level 2-Ereignissen in generischen Modellen, sodass Sie browserübergreifenden Code schreiben können, ohne sich über den Verlauf des IE als Rebell Gedanken machen zu müssen. Gleicher Code mit jQuery, alle browserübergreifend und bereit zum Rocken:
$(element).on('click', function () { /* do stuff */ });
Gehen Sie jedoch nicht aus und erhalten Sie einen Rahmen nur für diese eine Sache. Sie können ganz einfach Ihr eigenes kleines Dienstprogramm rollen, um sich um die älteren Browser zu kümmern:
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!'); }
);
Probieren Sie es aus: http://jsfiddle.net/bmArj/
Unter Berücksichtigung all dessen addEventListener
würde der verwendete Teil in IE-Versionen unter 9 nicht funktionieren , es sei denn, das Skript, das Sie sich ansehen, berücksichtigt die Browserunterschiede auf andere Weise (in Code, der in Ihrer Frage nicht gezeigt wird) .
Dokumentation und zugehöriges Lesen
function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }
function addEvent(e,n,f){return e.attachEvent?e.attachEvent('on'+n,f):e.addEventListener(n,f,!!0)}
<< Mit 98 Zeichen ist dieser mehr als 40% kleiner!Der Unterschied, den Sie sehen könnten, wenn Sie noch ein paar Funktionen hätten:
Die Funktionen 2, 3 und 4 funktionieren, 1 jedoch nicht. Dies liegt daran,
addEventListener
dass vorhandene Ereignishandler nicht überschrieben werden, währendonclick
vorhandeneonclick = fn
Ereignishandler überschrieben werden .Der andere wesentliche Unterschied besteht natürlich darin, dass er
onclick
immer funktioniert, währendaddEventListener
er in Internet Explorer vor Version 9 nicht funktioniert. Sie können die analogeattachEvent
(mit etwas anderer Syntax) in IE <9 verwenden.quelle
In dieser Antwort werde ich die drei Methoden zum Definieren von DOM-Ereignishandlern beschreiben.
element.addEventListener()
Codebeispiel:
Code-Snippet anzeigen
element.addEventListener()
hat mehrere Vorteile:element.removeEventListener()
.useCapture
Parameter, der angibt, ob Sie ein Ereignis in der Erfassungs- oder Blasenphase behandeln möchten . Siehe: Das useCapture-Attribut in addEventListener kann nicht verstanden werden ..onevent
Eigenschaften von DOM-Elementen denken viele unerfahrene JavaScript-Programmierer, dass der Ereignisname beispielsweiseonclick
oder lautetonload
.on
ist kein Teil des Ereignisnamens . Richtige Ereignisnamen sindclick
undload
, und so werden Ereignisnamen an übergeben.addEventListener()
.element.onevent = function() {}
(zonclick
,onload
)Codebeispiel:
Code-Snippet anzeigen
Dies war eine Möglichkeit, Ereignishandler in DOM 0 zu registrieren. Es wird jetzt davon abgeraten, weil:
onevent
Eigenschaft auf ihren ursprünglichen Zustand (dhnull
) zurücksetzen müssen .window.onload
, zum Beispielwindow.onload = "test";
:, werden keine Fehler ausgegeben. Ihr Code würde nicht funktionieren und es wäre wirklich schwer herauszufinden, warum..addEventListener()
würde jedoch einen Fehler auslösen (zumindest in Firefox): TypeError: Argument 2 von EventTarget.addEventListener ist kein Objekt .Inline-Ereignishandler (
onevent
HTML-Attribut)Codebeispiel:
Code-Snippet anzeigen
Ähnlich wie
element.onevent
es ist jetzt entmutigt. Neben den Problemen, die eselement.onevent
hat, ist es:Content-Security-Policy
HTTP-Header senden , um Inline-Skripte zu blockieren und externe Skripte nur von vertrauenswürdigen Domänen zuzulassen. Siehe Wie funktioniert die Inhaltssicherheitsrichtlinie?Siehe auch
EventTarget.addEventListener()
Dokumentation (MDN)EventTarget.removeEventListener()
Dokumentation (MDN)quelle
Funktioniert zwar
onclick
in allen Browsern,addEventListener
funktioniert jedoch nicht in älteren Versionen von Internet Explorer, dieattachEvent
stattdessen verwendet werden.Der Nachteil
onclick
ist, dass es nur einen Ereignishandler geben kann, während die anderen beiden alle registrierten Rückrufe auslösen.quelle
Soweit ich weiß, funktioniert das DOM-Ereignis "Laden" immer noch nur sehr begrenzt. Das heißt es wird nur für das Feuer
window object
,images
und<script>
Elemente zum Beispiel. Gleiches gilt für die direkteonload
Zuordnung. Es gibt keinen technischen Unterschied zwischen diesen beiden. Wahrscheinlich.onload =
eine bessere browserübergreifende Verfügbarkeit.Sie können jedoch
load event
einem<div>
oder einem<span>
Element oder so weiter kein a zuweisen .quelle
Zusammenfassung:
addEventListener
kann mehrere Ereignisse hinzufügen, währendonclick
dies nicht möglich ist.onclick
kann alsHTML
Attribut hinzugefügt werden, während einaddEventListener
nur innerhalb von<script>
Elementen hinzugefügt werden kann.addEventListener
kann ein drittes Argument annehmen, das die Ereignisausbreitung stoppen kann.Beide können zur Behandlung von Ereignissen verwendet werden. Sollte
addEventListener
jedoch die bevorzugte Wahl sein, da es alles kannonclick
und mehr. Verwenden Sie Inline nichtonclick
als HTML-Attribute, da dies das Javascript und das HTML vermischt, was eine schlechte Praxis ist. Dies macht den Code weniger wartbar.quelle
onclick
Handler verwenden, aus Angst, aus dem Raum gelacht zu werden - aber normalerweise sind die Ereignisse in den letzten Jahren viel schlimmer und weniger wartungsfähig. Klassen wiejs-link
,js-form-validation
oder Datenattribute mitdata-jspackage="init"
in keiner Weise besser ... Und wie ofteen tun Sie tatsächlich verwenden Ereignis sprudelnden? Ich persönlich würde gerne einen Handler schreiben können, ohne zu überprüfen, ob das Ziel tatsächlich mit meinem Element übereinstimmt - oder die Ausbreitung an mehreren Stellen aufgrund zufälliger Fehler stoppen zu müssen.Ein Detail wurde noch nicht bemerkt: Moderne Desktop-Browser betrachten unterschiedliche Tastendrücke als "Klicks" für
AddEventListener('click'
undonclick
standardmäßig.onclick
undAddEventListener
klicken Sie mit der linken und mittleren Maustaste auf Feuer.onclick
feuert nur auf der linken Maustaste, aberAddEventListener
klicken Feuer auf links, Mitte und rechts Klicks.Außerdem ist das Verhalten bei mittleren Klicks in allen Browsern sehr inkonsistent, wenn Bildlaufcursor beteiligt sind:
Es ist auch erwähnenswert, dass "Klick" -Ereignisse für jedes über die Tastatur auswählbare HTML-Element, z. B.
input
auch auf Leerzeichen ausgelöst oder eingegeben werden, wenn das Element ausgewählt wird.quelle
Javascript neigt dazu, alles in Objekte zu mischen, und das kann es verwirrend machen. Alles in einem ist der JavaScript-Weg.
Im Wesentlichen ist onclick ein HTML-Attribut. Umgekehrt ist addEventListener eine Methode für das DOM-Objekt, die ein HTML-Element darstellt.
In JavaScript-Objekten ist eine Methode lediglich eine Eigenschaft, die eine Funktion als Wert hat und gegen das Objekt arbeitet, an das sie angehängt ist (z. B. mit diesem).
In JavaScript als HTML-Element, das durch DOM dargestellt wird, werden die Attribute seinen Eigenschaften zugeordnet.
Hier werden die Leute verwirrt, weil JavaScript alles in einem einzigen Container oder Namespace ohne Indirektionsebene verschmilzt.
In einem normalen OO-Layout (das zumindest den Namespace von Eigenschaften / Methoden zusammenführt) könnten Sie Folgendes haben:
Es gibt Variationen, wie es einen Getter / Setter für Onload oder HashMap für Attribute verwenden könnte, aber letztendlich würde es so aussehen. JavaScript beseitigte diese Indirektionsebene in der Erwartung, unter anderem zu wissen, was was ist. DomElement und Attribute wurden zusammengeführt.
Vorbehaltlich der Kompatibilität sollten Sie als Best Practice addEventListener verwenden. Wenn andere Antworten eher über die diesbezüglichen Unterschiede als über die grundlegenden programmatischen Unterschiede sprechen, werde ich darauf verzichten. Im Grunde genommen sollten Sie in einer idealen Welt eigentlich nur * aus HTML verwenden, aber in einer noch idealeren Welt sollten Sie so etwas nicht aus HTML heraus tun.
Warum ist es heute dominant? Es ist schneller zu schreiben, leichter zu lernen und funktioniert meistens nur.
Der springende Punkt beim Onload in HTML besteht darin, zunächst Zugriff auf die Methode oder Funktionalität von addEventListener zu gewähren. Wenn Sie es in JS verwenden, durchlaufen Sie HTML, wenn Sie es direkt anwenden könnten.
Hypothetisch können Sie Ihre eigenen Attribute erstellen:
Was JS damit macht, ist etwas anders.
Sie können es mit etwas gleichsetzen (für jedes erstellte Element):
Die tatsächlichen Implementierungsdetails werden sich wahrscheinlich durch eine Reihe subtiler Variationen unterscheiden, wodurch sich die beiden in einigen Fällen geringfügig unterscheiden, aber das ist der Kern davon.
Es ist wohl ein Kompatibilitäts-Hack, dass Sie eine Funktion an ein on-Attribut anheften können, da standardmäßig alle Zeichenfolgen Zeichenfolgen sind.
quelle
Laut MDN ist der Unterschied wie folgt:
addEventListener:
onclick:
Es gibt auch einen Syntaxunterschied bei der Verwendung, wie Sie in den folgenden Codes sehen:
addEventListener:
onclick:
quelle
Wenn Sie sich keine Sorgen um die Browserunterstützung machen, können Sie die Referenz 'this' in der vom Ereignis aufgerufenen Funktion erneut binden. Normalerweise zeigt es auf das Element, das das Ereignis generiert hat, wenn die Funktion ausgeführt wird, was nicht immer das ist, was Sie wollen. Der schwierige Teil besteht darin, gleichzeitig denselben Ereignis-Listener entfernen zu können, wie in diesem Beispiel gezeigt: http://jsfiddle.net/roenbaeck/vBYu3/
Der obige Code funktioniert gut in Chrome, und es gibt wahrscheinlich einige Probleme damit, "Binden" mit anderen Browsern kompatibel zu machen.
quelle
Die Verwendung von Inline-Handlern ist nicht mit der Inhaltssicherheitsrichtlinie kompatibel, sodass der
addEventListener
Ansatz unter diesem Gesichtspunkt sicherer ist. Natürlich können Sie die Inline-Handler mit aktivieren,unsafe-inline
aber wie der Name schon sagt, ist dies nicht sicher, da es die ganzen Horden von JavaScript-Exploits zurückbringt, die CSP verhindert.quelle
Es sollte auch möglich sein, den Listener entweder durch Prototyping zu erweitern (wenn wir einen Verweis darauf haben und es sich nicht um eine anonyme Funktion handelt) oder den Aufruf "onclick" einen Aufruf einer Funktionsbibliothek (eine Funktion, die andere Funktionen aufruft) durchzuführen.
mögen
Dies bedeutet, dass wir den Onclick-Aufruf niemals ändern müssen, sondern nur die Funktion myFunctionList () ändern müssen, um zu tun, was immer wir wollen. Dies lässt uns jedoch ohne Kontrolle über die Blasen- / Fangphasen, sodass dies für neuere Browser vermieden werden sollte.
Nur für den Fall, dass jemand diesen Thread in Zukunft findet ...
quelle
Sie tun anscheinend dasselbe: Warten Sie auf das Klickereignis und führen Sie eine Rückruffunktion aus. Trotzdem sind sie nicht gleichwertig. Wenn Sie jemals zwischen den beiden wählen müssen, kann dies Ihnen helfen, herauszufinden, welches das beste für Sie ist.
Der Hauptunterschied besteht darin, dass onclick nur eine Eigenschaft ist und wie alle Objekteigenschaften überschrieben wird, wenn Sie mehr als einmal darauf schreiben . Mit addEventListener () können wir stattdessen einfach einen Ereignishandler an das Element binden und ihn jedes Mal aufrufen, wenn wir ihn benötigen, ohne uns um überschriebene Eigenschaften sorgen zu müssen. Beispiel wird hier gezeigt,
Probieren Sie es aus: https://jsfiddle.net/fjets5z4/5/
Erstens war ich versucht, weiterhin onclick zu verwenden, weil es kürzer ist und einfacher aussieht… und tatsächlich ist es das auch. Aber ich empfehle es nicht mehr. Es ist wie mit Inline-JavaScript. Die Verwendung von so etwas wie Inline-JavaScript wird heutzutage dringend empfohlen (Inline-CSS wird ebenfalls nicht empfohlen, aber das ist ein anderes Thema).
Die Funktion addEventListener () funktioniert jedoch, obwohl sie der Standard ist, in alten Browsern (Internet Explorer unter Version 9) nicht, und dies ist ein weiterer großer Unterschied. Wenn Sie diese alten Browser unterstützen müssen, sollten Sie dem Onclick-Weg folgen. Sie können aber auch jQuery (oder eine seiner Alternativen) verwenden: Es vereinfacht grundsätzlich Ihre Arbeit und verringert die Unterschiede zwischen den Browsern. Dadurch können Sie viel Zeit sparen.
quelle
addEventListener
Mit dieser Option können Sie mehrere Handler festlegen, die jedoch in IE8 oder niedriger nicht unterstützt werden.IE hat
attachEvent
, aber es ist nicht genau das gleiche.quelle
Der Kontext, auf den das
'this'
Schlüsselwort in JavasSript verweist, ist unterschiedlich.Schauen Sie sich den folgenden Code an:
Was es tut, ist wirklich einfach. Wenn Sie auf die Schaltfläche klicken, wird die Schaltfläche automatisch deaktiviert.
Wenn Sie zunächst versuchen, die Ereignisse auf diese Weise zu
button.onclick = function(),
verbinden, wird das Ereignis onclick durch Klicken auf die Schaltfläche ausgelöst. Die Schaltfläche wird jedoch nicht deaktiviert, da zwischen button.onclick und dem Ereignishandler onclick keine explizite Bindung besteht. Wenn Sie das'this'
Objekt debuggen, sehen Sie, dass es sich auf das'window'
Objekt bezieht .Zweitens können Sie beim Kommentieren
btnSubmit.onclick = disable();
und Kommentieren//btnSubmit.addEventListener('click', disable, false);
feststellen, dass die Schaltfläche deaktiviert ist, da auf diese Weise eine explizite Bindung zwischen dem Ereignis button.onclick und dem Ereignishandler onclick besteht. Wenn Sie in die Deaktivierungsfunktion debuggen, sehen Sie, dass'this'
sich diesbutton control
eher auf die als auf die beziehtwindow
.Dies ist etwas, das ich an JavaScript nicht mag, was inkonsistent ist. Übrigens, wenn Sie jQuery (
$('#btnSubmit').on('click', disable);
) verwenden, wird eine explizite Bindung verwendet.quelle
btnSubmit.onclick = disable;
(Funktion zuweisen, nicht aufrufen). In beiden Fällenthis
wird dann auf das Schaltflächenelement verwiesen.onclick ist im Grunde ein addEventListener, der speziell eine Funktion ausführt, wenn auf das Element geklickt wird. Nützlich, wenn Sie eine Schaltfläche haben, die einfache Operationen ausführt, z. B. eine Taschenrechner-Schaltfläche. addEventlistener kann für eine Vielzahl von Dingen verwendet werden, z. B. zum Ausführen einer Operation, wenn DOM oder der gesamte Inhalt geladen wird, ähnlich wie window.onload, jedoch mit mehr Kontrolle.
Hinweis: Sie können tatsächlich mehr als ein Ereignis mit Inline verwenden oder zumindest onclick verwenden, indem Sie jede Funktion mit einem Semikolon wie diesem trennen.
Ich würde keine Funktion mit Inline schreiben, da Sie möglicherweise später Probleme haben könnten und es imo chaotisch wäre. Verwenden Sie es einfach, um Funktionen aufzurufen, die bereits in Ihrer Skriptdatei ausgeführt wurden.
Welches Sie verwenden, hängt vermutlich davon ab, was Sie wollen. addEventListener für komplexe Operationen und onclick für einfache. Ich habe gesehen, dass einige Projekte kein bestimmtes Element an Elemente anhängen und stattdessen einen globaleren Ereignislistener implementieren, der bestimmt, ob auf eine Schaltfläche getippt wurde, und bestimmte Aufgaben ausführt, je nachdem, was gedrückt wurde. Imo, das möglicherweise zu Problemen führen könnte, würde ich denken, und wenn auch klein, wahrscheinlich eine Ressourcenverschwendung, wenn dieser Eventlistener jeden einzelnen Klick verarbeiten müsste
quelle