jQuery: Wie kann ich das Ereignisobjekt in einer Ereignishandlerfunktion abrufen, ohne es als Argument zu übergeben?

68

Ich habe ein onclickAttribut auf meinem Link:

<a href="#" onclick="myFunc(1,2,3)">click</a>

Das weist auf diesen Ereignishandler in JavaScript hin:

function myFunc(p1,p2,p3) {
    //need to refer to the current event object:
    alert(evt.type);        
}

Ist es immer noch möglich, dieses Objekt zu erhalten, da das Ereignisobjekt "evt" nicht an einen Parameter übergeben wird?

Ich habe es versucht window.eventund $(window.event), aber beide sind es undefined.

Irgendeine Idee?

LazNiko
quelle

Antworten:

98

Ist es immer noch möglich, dieses Objekt zu erhalten, da das Ereignisobjekt "evt" nicht vom Parameter übergeben wird?

Nein, nicht zuverlässig. IE und einige andere Browser stellen es als window.event(nicht $(window.event)) zur Verfügung, aber das ist nicht Standard und wird nicht von allen Browsern unterstützt (bekanntlich Firefox nicht).

Übergeben Sie das Ereignisobjekt besser an die Funktion:

<a href="#" onclick="myFunc(event, 1,2,3)">click</a>

Dies funktioniert auch in Nicht-IE-Browsern, da sie den Code in einem Kontext ausführen, der eine eventVariable enthält (und in IE, weil eventin aufgelöst wird window.event). Ich habe es in IE6 +, Firefox, Chrome, Safari und Opera versucht. Beispiel: http://jsbin.com/iwifu4

Aber Ihre beste Wette ist , modernes Event - Handling zu verwenden:

HTML:

<a href="#">click</a>

JavaScript mit jQuery (da Sie jQuery verwenden):

$("selector_for_the_anchor").click(function(event) {
    // Call `myFunc`
    myFunc(1, 2, 3);

    // Use `event` here at the event handler level, for instance
    event.stopPropagation();
});

... oder wenn Sie wirklich passieren wollen eventin myFunc:

$("selector_for_the_anchor").click(function(event) {
    myFunc(event, 1, 2, 3);
});

Der Selektor kann alles sein, was den Anker identifiziert. Sie haben eine sehr umfangreiche Auswahl (fast alle CSS3-Dateien plus einige). Sie können dem Anker ein idoder hinzufügen class, aber auch hier haben Sie andere Möglichkeiten. Wenn Sie verwenden können, wo es sich im Dokument befindet, anstatt etwas Künstliches hinzuzufügen, ist das großartig.

TJ Crowder
quelle
5
Vielen Dank für diese Erklärung, dieser Teil von Javascript hat mich immer verwirrt. Die Idee, dass dieser unsichtbare, mystische "Ereignis" -Parameter aus dem Nichts übergeben wird, wurde mir nie gut erklärt.
Kapitän Hypertext
15

In IE können Sie das Ereignisobjekt window.event in anderen Browsern ohne 'use strict'Anweisung abrufen. Es ist möglich, durchzukommen arguments.callee.caller.arguments[0].

function myFunc(p1, p2, p3) {
    var evt = window.event || arguments.callee.caller.arguments[0];
}
otakustay
quelle
1
argumente.callee.caller.arguments erwartet weiterhin, dass das Ereignis als Parameter / Argument übergeben wird.
Caspar Kleijne
Das würde nicht funktionieren. Die Funktion wird explizit vom Ereignishandler ohne den Ereignisparameter aufgerufen , sodass nicht als Argument darauf zugegriffen werden kann.
Pointy
1
Ich habe es auf Chrome getestet und es funktioniert. Das Ereignisobjekt ist ein implizites Argument für ein HTML-Inline-Ereignis und arguments.callee.callereine von HTML generierte anonyme Ereignishandlerfunktion. Das erste Argument ist implizit das Ereignisobjekt
otakustay
6
arguments.callee.callerwird nicht allgemein unterstützt, ist in einigen Implementierungen, in denen es unterstützt wird, massiv langsam, ist eine wirklich schlechte Idee und wird im strengen Modus nicht zugelassen.
TJ Crowder
1
Richtig, Angerufene und Anrufer werden entmutigt, aber es ist die einzige Möglichkeit, auf das Ereignisobjekt zuzugreifen, wenn der Code für die Ereignisbehandlung in HTML
eingefügt
4

Schreiben Sie Ihre Event-Handler-Erklärung wie folgt:

<a href="#" onclick="myFunc(event,1,2,3)">click</a>

Dann kann Ihre Funktion "myFunc ()" auf das Ereignis zugreifen.

Der Zeichenfolgenwert des Attributs "onclick" wird auf eine Weise in eine Funktion konvertiert, die fast genau der des Browsers (intern) entspricht, der den Funktionskonstruktor aufruft:

theAnchor.onclick = new Function("event", theOnclickString);

(außer im IE). Da "event" im IE ein globales Ereignis ist (es ist ein Fensterattribut), können Sie es in jedem Browser auf diese Weise an die Funktion übergeben.

Spitze
quelle
in FF getestet und Sie hatten Recht, es ist schwer gescheitert. Löschte den Beitrag, bevor die Flut von Abstimmungen kam. Vielen Dank für die Heads-Ups :)
JohnP
1

Wenn Sie Ihren Event-Handler beim Markup aufrufen, wie Sie es jetzt tun, können Sie dies nicht (X-Browser). Wenn Sie das Klickereignis jedoch mit jquery binden, ist dies folgendermaßen möglich:

Markup:

  <a href="#" id="link1" >click</a>

Javascript:

  $(document).ready(function(){
      $("#link1").click(clickWithEvent);  //Bind the click event to the link
  });
  function clickWithEvent(evt){
     myFunc('p1', 'p2', 'p3');
     function myFunc(p1,p2,p3){  //Defined as local function, but has access to evt
        alert(evt.type);        
     }
  }

Da die Veranstaltung ob

Edgar Villegas Alvarado
quelle
1
"Wenn Sie Ihren Event-Handler beim Markup aufrufen, wie Sie es jetzt tun, können Sie dies nicht (X-Browser)." Eigentlich können Sie (siehe meine Antwort; das funktioniert in allen gängigen und allen kleineren Browsern, die ich je ausprobiert habe - IE6 +, Firefox, Chrome, Safari, Opera ...). Aber es ist wahrscheinlich am besten, es nicht zu tun.
TJ Crowder
In Ihrer Lösung senden Sie jedoch eventals Parameter, und LazNiko verlangt dies nicht. Es muss einen anderen Weg geben, aber er ist wertlos, da der Fragesteller weg ist: S
Edgar Villegas Alvarado
Ein Ansatz (unter Verwendung von Markup) wäre in der Tat, die clickWithEventFunktion vom Markup aus aufzurufen , aber wie wir wissen, ist das Aufrufen vom Markup nicht der beste Weg (und es wäre am Ende die gleiche Lösung).
Edgar Villegas Alvarado