2012-04-03 16 views
46

Ich möchte einen EventHandler, der das Ereignis und einige Parameter übergibt. Das Problem ist, dass die Funktion das Element nicht erhält. Hier ein Beispiel:Javascript Event-Handler mit Parametern

doClick = function(func){ 
    var elem = .. // the element where it is all about 
    elem.onclick = function(e){ 
     func(e, elem); 
    } 
} 
doClick(function(e, element){ 
    // do stuff with element and the event 
}); 

Der 'elem' muss außerhalb der anonymen Funktion definiert werden. Wie kann ich das übergebene Element innerhalb der anonymen Funktion verwenden? Gibt es eine Möglichkeit, dies zu tun?

Und was ist mit addEventListener? Ich bin anscheinend nicht in der Lage, das Ereignis durch einen addEventListener überhaupt zu übertragen, oder?

aktualisiert

Ich schien das Problem mit 'this'

doClick = function(func){ 
    var that = this; 
    this.element.onclick = function(e){ 
     func(e, that); 
    } 
} 

Wo dies enthält this.element zu beheben, dass ich in der Funktion zugreifen kann.

Die addEventListener

Aber ich frage mich, über die addEventListener:

function doClick(elem, func){ 
    element.addEventListener('click', func(event, elem), false); 
} 
+1

Sie haben Elem, Elemente, Element in Ihrer Frage beteiligt. Kannst du weniger verwirrend sein? – mihai

+0

Es tut mir leid, ich habe versucht, ein Beispiel für meine Situation zu machen, aber das ist nicht gut gelaufen, ich habe den Code aktualisiert. – sebas2day

+0

Würden Sie nach 'e.target' /' e.currentTarget' suchen? – Rolf

Antwort

56

Ich verstehe nicht genau, was Ihr Code versucht zu tun, aber Sie können Variablen in jeder zur Verfügung stellen Event-Handler die Vorteile der Funktion Verschlüsse mit:

function addClickHandler(elem, arg1, arg2) { 
    elem.addEventListener('click', function(e) { 
     // in the event handler function here, you can directly refer 
     // to arg1 and arg2 from the parent function arguments 
    }, false); 
} 

Je nach Ihren genauen Codierung si Sie können praktisch immer eine Art von Schließung vornehmen, um den Zugriff auf die Variablen für Sie zu erhalten.

Von Ihre Kommentare, wenn das, was Sie versuchen, ist, dies zu erreichen:

element.addEventListener('click', func(event, this.elements[i])) 

Dann Sie diese mit einer selbst ausgeführte Funktion (IIFE) tun können, dass die Argumente, die Sie in einem Verschluss wollen einfängt als es führt und gibt die aktuelle Funktion Ereignishandler:

element.addEventListener('click', (function(passedInElement) { 
    return function(e) {func(e, passedInElement); }; 
}) (this.elements[i]), false); 

weitere Informationen darüber, wie ein IIFE Werke, diese Referenzen sehen:

Javascript wrapping code inside anonymous function

Immediately-Invoked Function Expression (IIFE) In JavaScript - Passing jQuery

What are good use cases for JavaScript self executing anonymous functions?

Diese letzte Version ist vielleicht leichter zu sehen, wie es ist, dies zu tun:

// return our event handler while capturing an argument in the closure 
function handleEvent(passedInElement) { 
    return function(e) { 
     func(e, passedInElement); 
    }; 
} 

element.addEventListener('click', handleEvent(this.elements[i])); 

Es ist auch möglich .bind() zu verwenden Argumente hinzuzufügen ein Rückruf Alle Argumente, die Sie an .bind() übergeben, werden den Argumenten vorangestellt, die der Callback selbst haben wird. Also, Sie könnten dies tun:

elem.addEventListener('click', function(a1, a2, e) { 
    // inside the event handler, you have access to both your arguments 
    // and the event object that the event handler passes 
}.bind(elem, arg1, arg2)); 
+0

ja das ist fast das, was ich versuche zu tun, aber was ist, wenn die anonyme Funktion von addClickHandler als Parameter übergeben werden und Sie wollen dieser Funktion einige Parameter mit dem Ereignis wie: element.addEventListener ('click', func (event , diese Elemente [i])); – sebas2day

+2

@ sebas2day - Sie können nicht 'element.addEventListener ('click', func (event, this.elements [i]))' '. Javascript funktioniert einfach nicht so. Es gibt andere Wege, die mit Verschlüssen arbeiten, aber Sie können es nicht so machen, wie Sie es geschrieben haben. addEventListener ruft seinen Rückruf mit genau einem Argument (dem Ereignis) auf und Sie können das in keiner Weise ändern. – jfriend00

+0

Ich fügte ein weiteres Beispiel dafür hinzu, dies am Ende meiner Antwort zu tun. – jfriend00

0

this innerhalb von doThings ist das Fenster-Objekt.Versuchen Sie stattdessen:

var doThings = function (element) { 
    var eventHandler = function(ev, func){ 
     if (element[ev] == undefined) { 
      return; 
     } 

     element[ev] = function(e){ 
      func(e, element); 
     } 
    }; 

    return { 
     eventHandler: eventHandler 
    }; 
}; 
6

Etwas, das Sie versuchen können, ist die bind-Methode, ich denke, das erreicht, was Sie fragen. Wenn nichts anderes, ist es immer noch sehr nützlich.

function doClick(elem, func) { 
    var diffElem = document.getElementById('some_element'); //could be the same or different element than the element in the doClick argument 
    diffElem.addEventListener('click', func.bind(diffElem, elem)) 
} 

function clickEvent(elem, evt) { 
    console.log(this); 
    console.log(elem); 
    // 'this' and elem can be the same thing if the first parameter 
    // of the bind method is the element the event is being attached to from the argument passed to doClick 
    console.log(evt); 
} 

var elem = document.getElementById('elem_to_do_stuff_with'); 
doClick(elem, clickEvent); 
2

das Update auf die ursprüngliche Frage gegeben, wie es scheint, gibt es Probleme mit dem Kontext („this“) ist, während Event-Handler übergeben. Die Grundlagen werden z.B. hier http://www.w3schools.com/js/js_function_invocation.asp

Eine einfache Arbeitsversion Ihres Beispiels könnte lesen

var doClick = function(event, additionalParameter){ 
    // do stuff with event and this being the triggering event and caller 
} 

element.addEventListener('click', function(event) 
{ 
    var additionalParameter = ...; 
    doClick.call(this, event, additionalParameter); 
}, false); 

auch Javascript call() & apply() vs bind()?

-1
let obj = MyObject(); 

elem.someEvent(function(){ obj.func(param) }); 

//calls the MyObject.func, passing the param. 
+0

Wie löst dies das Problem des OP? – RamenChef

+0

param kann auch eine Callback-Funktion sein (im -say-globalen Kontext) und kann daher leicht mit den angeforderten Parametern zurückgerufen werden. –

1

Es ist eine alte Frage, aber ein allgemeiner See. Lass mich das hier hinzufügen.

Mit ES2015 Syntax können Sie ihm prägnante Weise erreichen:

function event_handler(event, arg) { 
    console.log(event, arg); 
} 

element.addEventListener('click', (event) => event_handler(event, 'Here comes the argument'));