addEventListener vs onclick

704

Was ist der Unterschied zwischen addEventListenerund onclick?

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

Der obige Code befindet sich zusammen in einer separaten .js-Datei und beide funktionieren einwandfrei.

William Sham
quelle

Antworten:

956

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 addEventListenerist 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 attachEventoder 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 onclickEigenschaft mit dem zweiten Wert überschrieben und auch die ursprüngliche Inline-HTML- onclickEigenschaft. Ü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 addEventListenerwü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

Chris Baker
quelle
14
Es tut mir leid, aber ich wollte nur eine komprimierte Version Ihrer Funktion geben (Geige: jsfiddle.net/bmArj/153 ) -function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }
Deryck
10
@Gaurav_soni Nein. Der Name der Funktion und der gesamte darin enthaltene Code sind bereits in der Javascript-Datei verfügbar, die im Klartext vorliegt. Jeder kann eine Webkonsole öffnen und Javascript ausführen oder bearbeiten. Wenn Ihr Javascript etwas enthält, das ein Sicherheitsrisiko darstellen könnte, wenn es der Öffentlichkeit ausgesetzt ist, haben Sie ein großes Problem, da es bereits der Öffentlichkeit ausgesetzt ist.
Chris Baker
4
Solange wir diesen Algorithmus komprimieren, können wir genauso gut den ganzen Weg gehen: 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!
Trevor
3
@ Trevor Aus Neugier, warum !! 0? Warum nicht! 1 oder nur 0?
Chris Baker
2
@AdrianMoisa Diese Antwort wurde zu einer Zeit geschrieben, als AngularJS eine neue Sache auf dem Vormarsch war und die übliche Praxis immer noch "progressive Verbesserung" war - das heißt, ein HTML-Dokument so zu schreiben, dass es mit oder ohne Javascript funktioniert. In dieser Perspektive wäre das Binden von Ereignissen aus Javascript eine bewährte Methode. Heutzutage denke ich nicht, dass sich viele Menschen zu viele Sorgen um die fortschreitende Verbesserung machen, insbesondere wenn man die Verbreitung von Dingen wie Angular nicht berücksichtigt. Es gibt immer noch einige getrennte Argumente zu Inline-Ereignissen (ohne Angular), aber das ist mehr Stil als Substanz.
Chris Baker
193

Der Unterschied, den Sie sehen könnten, wenn Sie noch ein paar Funktionen hätten:

var h = document.getElementById('a');
h.onclick = doThing_1;
h.onclick = doThing_2;

h.addEventListener('click', doThing_3);
h.addEventListener('click', doThing_4);

Die Funktionen 2, 3 und 4 funktionieren, 1 jedoch nicht. Dies liegt daran, addEventListenerdass vorhandene Ereignishandler nicht überschrieben werden, während onclickvorhandene onclick = fnEreignishandler überschrieben werden .

Der andere wesentliche Unterschied besteht natürlich darin, dass er onclickimmer funktioniert, während addEventListenerer in Internet Explorer vor Version 9 nicht funktioniert. Sie können die analoge attachEvent(mit etwas anderer Syntax) in IE <9 verwenden.

einsamer Tag
quelle
18
Das ist eine sehr klare Erklärung! Auf den Punkt gebracht. Wenn ich also mehrere Funktionen für ein Ereignis benötige, bleibe ich bei addEventListener und muss mehr Code für attachEvent schreiben, um den IE unterzubringen.
William Sham
4
2, 3 und 4 sollten als dosomething bezeichnet werden. 1 wird von 2 überschrieben und nie aufgerufen.
DragonLord
In der Tat eine sehr klare und auf den Punkt gebrachte Erklärung. Sei es, dass es in der Tat viel sinnvoller wäre, die Funktionen 'doThing_1' usw. zu nennen. (Wenn Sie immer noch IE <9 berücksichtigen möchten, lesen Sie die Antwort von Chris.)
Frank Conijn
61

In dieser Antwort werde ich die drei Methoden zum Definieren von DOM-Ereignishandlern beschreiben.

element.addEventListener()

Codebeispiel:

element.addEventListener() hat mehrere Vorteile:

  • Ermöglicht es Ihnen, unbegrenzte Ereignishandler zu registrieren und mit zu entfernen element.removeEventListener().
  • Hat einen useCaptureParameter, der angibt, ob Sie ein Ereignis in der Erfassungs- oder Blasenphase behandeln möchten . Siehe: Das useCapture-Attribut in addEventListener kann nicht verstanden werden .
  • Kümmert sich um Semantik . Grundsätzlich wird die Registrierung von Ereignishandlern expliziter. Für einen Anfänger macht ein Funktionsaufruf deutlich, dass etwas passiert , während das Zuweisen eines Ereignisses zu einer Eigenschaft des DOM-Elements zumindest nicht intuitiv ist.
  • Ermöglicht die Trennung von Dokumentstruktur (HTML) und Logik (JavaScript) . In winzigen Webanwendungen scheint es nicht wichtig zu sein, aber es spielt bei jedem größeren Projekt eine Rolle. Es ist viel einfacher, ein Projekt zu pflegen, das Struktur und Logik trennt, als ein Projekt, das dies nicht tut.
  • Beseitigt Verwechslungen mit korrekten Ereignisnamen. Aufgrund der Verwendung von Inline-Ereignis-Listenern oder der Zuweisung von Ereignis-Listenern zu .oneventEigenschaften von DOM-Elementen denken viele unerfahrene JavaScript-Programmierer, dass der Ereignisname beispielsweise onclickoder lautet onload. onist kein Teil des Ereignisnamens . Richtige Ereignisnamen sind clickund load, und so werden Ereignisnamen an übergeben .addEventListener().
  • Funktioniert in fast allen Browsern . Wenn Sie IE <= 8 weiterhin unterstützen müssen, können Sie eine Polyfüllung aus MDN verwenden .

element.onevent = function() {}(z onclick, onload)

Codebeispiel:

Dies war eine Möglichkeit, Ereignishandler in DOM 0 zu registrieren. Es wird jetzt davon abgeraten, weil:

  • Ermöglicht die Registrierung nur eines Ereignishandlers. Das Entfernen des zugewiesenen Handlers ist auch nicht intuitiv, da Sie zum Entfernen des mit dieser Methode zugewiesenen Ereignishandlers die oneventEigenschaft auf ihren ursprünglichen Zustand (dh null) zurücksetzen müssen .
  • Reagiert nicht angemessen auf Fehler . Wenn Sie beispielsweise versehentlich eine Zeichenfolge zuweisen window.onload, zum Beispiel window.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 .
  • Bietet keine Möglichkeit zur Auswahl, ob Sie ein Ereignis in der Erfassungs- oder Blasenphase behandeln möchten.

Inline-Ereignishandler ( oneventHTML-Attribut)

Codebeispiel:

Ähnlich wie element.oneventes ist jetzt entmutigt. Neben den Problemen, die es element.oneventhat, ist es:

  • Ist ein potenzielles Sicherheitsproblem , da es XSS viel schädlicher macht. Heutzutage sollten Websites einen geeigneten Content-Security-PolicyHTTP-Header senden , um Inline-Skripte zu blockieren und externe Skripte nur von vertrauenswürdigen Domänen zuzulassen. Siehe Wie funktioniert die Inhaltssicherheitsrichtlinie?
  • Trennt Dokumentstruktur und Logik nicht .
  • Wenn Sie Ihre Seite mit einem serverseitigen Skript generieren und beispielsweise hundert Links mit jeweils demselben Inline-Ereignishandler generieren, ist Ihr Code viel länger als wenn der Ereignishandler nur einmal definiert wurde. Das bedeutet, dass der Client mehr Inhalte herunterladen müsste und Ihre Website daher langsamer wäre.

Siehe auch

Michał Perłakowski
quelle
22

Funktioniert zwar onclickin allen Browsern, addEventListenerfunktioniert jedoch nicht in älteren Versionen von Internet Explorer, die attachEventstattdessen verwendet werden.

Der Nachteil onclickist, dass es nur einen Ereignishandler geben kann, während die anderen beiden alle registrierten Rückrufe auslösen.

Magnar
quelle
12

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, imagesund <script>Elemente zum Beispiel. Gleiches gilt für die direkte onloadZuordnung. Es gibt keinen technischen Unterschied zwischen diesen beiden. Wahrscheinlich.onload = eine bessere browserübergreifende Verfügbarkeit.

Sie können jedoch load eventeinem <div>oder einem <span>Element oder so weiter kein a zuweisen .

jAndy
quelle
9

Zusammenfassung:

  1. addEventListenerkann mehrere Ereignisse hinzufügen, während onclickdies nicht möglich ist.
  2. onclickkann als HTMLAttribut hinzugefügt werden, während ein addEventListenernur innerhalb von <script>Elementen hinzugefügt werden kann.
  3. addEventListener kann ein drittes Argument annehmen, das die Ereignisausbreitung stoppen kann.

Beide können zur Behandlung von Ereignissen verwendet werden. Sollte addEventListenerjedoch die bevorzugte Wahl sein, da es alles kann onclick und mehr. Verwenden Sie Inline nicht onclickals HTML-Attribute, da dies das Javascript und das HTML vermischt, was eine schlechte Praxis ist. Dies macht den Code weniger wartbar.

Willem van der Veen
quelle
Und wie wird das Element-Targeting meistens durchgeführt? Ich meine, ich persönlich werde keine Inline- onclickHandler 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 wie js-link, js-form-validationoder Datenattribute mit data-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.
Christoffer Bubach
3

Ein Detail wurde noch nicht bemerkt: Moderne Desktop-Browser betrachten unterschiedliche Tastendrücke als "Klicks" für AddEventListener('click'und onclickstandardmäßig.

  • Bei Chrome 42 und IE11 beide onclickund AddEventListenerklicken Sie mit der linken und mittleren Maustaste auf Feuer.
  • Auf 38 Firefox, onclickfeuert nur auf der linken Maustaste, aber AddEventListenerklicken Feuer auf links, Mitte und rechts Klicks.

Außerdem ist das Verhalten bei mittleren Klicks in allen Browsern sehr inkonsistent, wenn Bildlaufcursor beteiligt sind:

  • In Firefox werden Ereignisse mit mittlerem Klick immer ausgelöst.
  • In Chrome werden sie nicht ausgelöst, wenn der mittlere Klick einen Bildlaufcursor öffnet oder schließt.
  • Im IE werden sie ausgelöst, wenn der Bildlaufcursor geschlossen wird, nicht jedoch, wenn er geöffnet wird.

Es ist auch erwähnenswert, dass "Klick" -Ereignisse für jedes über die Tastatur auswählbare HTML-Element, z. B. inputauch auf Leerzeichen ausgelöst oder eingegeben werden, wenn das Element ausgewählt wird.

ein Gast
quelle
2

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:

domElement.addEventListener // Object(Method)
domElement.attributes.onload // Object(Property(Object(Property(String))))

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:

$('[myclick]').each(function(i, v) {
     v.addEventListener('click', function() {
         eval(v.myclick); // eval($(v).attr('myclick'));
     });
});

Was JS damit macht, ist etwas anders.

Sie können es mit etwas gleichsetzen (für jedes erstellte Element):

element.addEventListener('click', function() {
    switch(typeof element.onclick) {
          case 'string':eval(element.onclick);break;
          case 'function':element.onclick();break;
     }
});

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.

jgmjgm
quelle
2

Laut MDN ist der Unterschied wie folgt:

addEventListener:

Die EventTarget.addEventListener () -Methode fügt das angegebene EventListener-kompatible Objekt zur Liste der Ereignis-Listener für den angegebenen Ereignistyp in dem EventTarget hinzu, für das es aufgerufen wird. Das Ereignisziel kann ein Element in einem Dokument, das Dokument selbst, ein Fenster oder ein anderes Objekt sein, das Ereignisse unterstützt (z. B. XMLHttpRequest).

onclick:

Die onclick-Eigenschaft gibt den Klickereignishandlercode für das aktuelle Element zurück. Wenn Sie das Klickereignis zum Auslösen einer Aktion verwenden, sollten Sie auch erwägen, dieselbe Aktion zum Keydown-Ereignis hinzuzufügen, damit Personen, die keine Maus oder keinen Touchscreen verwenden, dieselbe Aktion verwenden können. Syntax element.onclick = functionRef; Dabei ist functionRef eine Funktion - häufig ein Name einer an anderer Stelle deklarierten Funktion oder ein Funktionsausdruck. Weitere Informationen finden Sie im "JavaScript-Handbuch: Funktionen".

Es gibt auch einen Syntaxunterschied bei der Verwendung, wie Sie in den folgenden Codes sehen:

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!");
}
Alireza
quelle
1

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/

/*
    Testing that the function returned from bind is rereferenceable, 
    such that it can be added and removed as an event listener.
*/
function MyImportantCalloutToYou(message, otherMessage) {
    // the following is necessary as calling bind again does 
    // not return the same function, so instead we replace the 
    // original function with the one bound to this instance
    this.swap = this.swap.bind(this); 
    this.element = document.createElement('div');
    this.element.addEventListener('click', this.swap, false);
    document.body.appendChild(this.element);
}
MyImportantCalloutToYou.prototype = {
    element: null,
    swap: function() {
        // now this function can be properly removed 
        this.element.removeEventListener('click', this.swap, false);           
    }
}

Der obige Code funktioniert gut in Chrome, und es gibt wahrscheinlich einige Probleme damit, "Binden" mit anderen Browsern kompatibel zu machen.

Lars Rönnbäck
quelle
1

Die Verwendung von Inline-Handlern ist nicht mit der Inhaltssicherheitsrichtlinie kompatibel, sodass der addEventListenerAnsatz unter diesem Gesichtspunkt sicherer ist. Natürlich können Sie die Inline-Handler mit aktivieren, unsafe-inlineaber wie der Name schon sagt, ist dies nicht sicher, da es die ganzen Horden von JavaScript-Exploits zurückbringt, die CSP verhindert.

Kravietz
quelle
1
Hinweis: Diese Sicherheitsbeschränkung gilt nur für die Erweiterungsentwicklung, und die im verknüpften Dokument angebotenen Sicherheitsbegründungen gelten größtenteils nur für die Entwicklung von Browsererweiterungen. Der einzige Punkt im verknüpften Dokument, der auch für die Webentwicklung im Allgemeinen gilt, ist die Trennung von Inhalt und Verhalten. Das ist auf ganzer Linie eine gute Praxis.
Chris Baker
1

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

    elm.onclick = myFunctionList
    function myFunctionList(){
      myFunc1();
      myFunc2();
    }

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

Patrik
quelle
1

element.onclick = function () {/ * mache Sachen * /}

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

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.

var clickEvent = document.getElementByID("onclick-eg");
var EventListener = document.getElementByID("addEventListener-eg");

clickEvent.onclick = function(){
    window.alert("1 is not called")
}
clickEvent.onclick = function(){
    window.alert("2 is not called")
}

EventListener.addEventListener("click",function(){
    window.alert("1 is called")
})
EventListener.addEventListener("click",function(){
    window.alert("2 is also called")
})
Arham Chowdhury
quelle
0

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.

user113716
quelle
0

Der Kontext, auf den das 'this'Schlüsselwort in JavasSript verweist, ist unterschiedlich.

Schauen Sie sich den folgenden Code an:

<!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>

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 dies button controleher auf die als auf die bezieht window.

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.

Larry
quelle
8
Sie müssen schreiben btnSubmit.onclick = disable;(Funktion zuweisen, nicht aufrufen). In beiden Fällen thiswird dann auf das Schaltflächenelement verwiesen.
Pascha
-1

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

ThatOneNoob
quelle