Chcę utworzyć eventHandler, który przekazuje zdarzenie i niektóre parametry. Problem w tym, że funkcja nie pobiera elementu. Oto przykład:
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
});
Element „elem” musi być zdefiniowany poza funkcją anonimową. Jak mogę uzyskać przekazany element do użycia w funkcji anonimowej? Czy jest na to sposób?
A co z addEventListener? Wydaje się, że w ogóle nie mogę przekazać zdarzenia przez addEventListener, prawda?
Aktualizacja
Wydawało się, że rozwiązałem problem z „tym”
doClick = function(func){
var that = this;
this.element.onclick = function(e){
func(e, that);
}
}
Gdzie ten element zawiera this.element, do którego mam dostęp w funkcji.
AddEventListener
Ale zastanawiam się nad addEventListener:
function doClick(elem, func){
element.addEventListener('click', func(event, elem), false);
}
javascript
events
event-handling
handler
sebas2day
źródło
źródło
e.target
/e.currentTarget
?Odpowiedzi:
Nie rozumiem dokładnie, co próbuje zrobić Twój kod, ale możesz udostępnić zmienne w dowolnym programie obsługi zdarzeń, korzystając z zalet zamknięć funkcji:
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); }
W zależności od dokładnej sytuacji kodowania, prawie zawsze możesz dokonać pewnego rodzaju zamknięcia, aby zachować dostęp do zmiennych.
Z twoich komentarzy, jeśli próbujesz osiągnąć to:
element.addEventListener('click', func(event, this.elements[i]))
Następnie możesz to zrobić za pomocą samo wykonującej się funkcji (IIFE), która przechwytuje argumenty, które chcesz w zamknięciu, podczas wykonywania i zwraca rzeczywistą funkcję obsługi zdarzenia:
element.addEventListener('click', (function(passedInElement) { return function(e) {func(e, passedInElement); }; }) (this.elements[i]), false);
Aby uzyskać więcej informacji na temat działania IIFE, zobacz te inne źródła:
JavaScript opakowujący kod wewnątrz funkcji anonimowej
Wyrażenie funkcji wywoływane natychmiastowo (IIFE) w JavaScript - przekazywanie jQuery
Jakie są dobre przypadki użycia dla samodzielnie wykonujących się anonimowych funkcji JavaScript?
Ta ostatnia wersja może być łatwiejsza do zobaczenia, co robi w ten sposób:
// 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]));
Możliwe jest również użycie
.bind()
do dodania argumentów do wywołania zwrotnego. Wszelkie argumenty, do których.bind()
przekażesz, zostaną dołączone do argumentów, które będzie miało samo wywołanie zwrotne. Możesz więc zrobić to: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));
źródło
element.addEventListener('click', func(event, this.elements[i]))
. JavaScript po prostu nie działa w ten sposób. Są inne sposoby obejścia tego, używając domknięć, ale nie możesz tego zrobić tak, jak napisałeś. addEventListener wywołuje wywołanie zwrotne z dokładnie jednym argumentem (zdarzeniem) i nie możesz tego w żaden sposób zmienić.function eventFunction (arg, evt) { console.log(arg[0],arg[1],arg[2]) console.log(evt) } var el = document.getElementById('elementID'); el.addEventListener('click', eventFunction.bind(el,[1,2,3]))
Należy zauważyć, że argument zdarzenia jest zawsze ostatni w argumentach funkcji i nie jest jawnie deklarowany w metodzie bind.To stare pytanie, ale powszechne. Więc pozwól mi dodać ten tutaj.
Dzięki składni funkcji strzałek można uzyskać bardziej zwięzły sposób, ponieważ jest ona powiązana leksykalnie i można ją połączyć w łańcuch.
Wyrażenie funkcji strzałkowej jest kompaktową pod względem składniowym alternatywą dla wyrażenia funkcji regularnej, chociaż nie ma własnych powiązań ze słowami kluczowymi this, arguments, super lub new.target.
const event_handler = (event, arg) => console.log(event, arg); el.addEventListener('click', (event) => event_handler(event, 'An argument'));
Jeśli chcesz wyczyścić detektor zdarzeń:
// Let's use use good old function sytax function event_handler(event, arg) { console.log(event, arg); } // Assign the listener callback to a variable var doClick = (event) => event_handler(event, 'An argument'); el.addEventListener('click', doClick); // Do some work... // Then later in the code, clean up el.removeEventListener('click', doClick);
Oto szalona jedna linijka:
// You can replace console.log with some other callback function el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));
Bardziej potulna wersja : bardziej odpowiednia do każdej rozsądnej pracy.
el.addEventListener('click', (event) => ((arg) => { console.log(event, arg); })('An argument'));
źródło
this
i opiekun mógł uzyskać dostęp do tego, czego potrzebuje.Coś, co możesz spróbować, to użycie metody wiązania, myślę, że to osiąga to, o co prosiłeś. Jeśli nic więcej, nadal jest bardzo przydatne.
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);
źródło
Biorąc pod uwagę aktualizację pierwotnego pytania, wydaje się, że wystąpił problem z kontekstem („to”) podczas przekazywania programów obsługi zdarzeń. Podstawy są wyjaśnione np. Tutaj http://www.w3schools.com/js/js_function_invocation.asp
Prosta działająca wersja twojego przykładu mogłaby czytać
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);
Zobacz także wywołanie () i zastosowanie () w JavaScript vs bind ()?
źródło
Krótka odpowiedź:
x.addEventListener("click", function(e){myfunction(e, param1, param2)}); ... function myfunction(e, param1, param1) { ... }
źródło
param1
lubparam2
. Jeśli te wartości ulegną zmianie, nie zostaną ustawione na wartość, która była w czasie tworzenia procedury obsługi zdarzeń. Zostaną ustawione tylko na aktualną wartość. Ponadto nie różni się to od ustawiania zmiennej poza zakresem funkcji detektora zdarzeń i odwoływania się do tej zmiennej w module obsługi zdarzeń, więc w ogóle nie dokonuje przekazywania parametrów.param1
jestnoodle
to pierwsze wywołanie addEventListener, a drugie wywołanie go,param
tocheese
wtedy, gdy wywoła się detektor zdarzeniaclick
,param1
zostanie ustawione na,cheese
a nienoodle
. Dlatego nie używa „zamknięcia” do zapamiętania wartości, która istniała w momencie dodawania detektora zdarzeń. Istnieją scenariusze, w których odbiornik zdarzeń musi być dodawany wiele razy, których nie trzeba ilustrować, aby mój punkt widzenia był ważny.this
wewnątrzdoThings
znajduje się obiekt okna. Spróbuj tego zamiast tego:var doThings = function (element) { var eventHandler = function(ev, func){ if (element[ev] == undefined) { return; } element[ev] = function(e){ func(e, element); } }; return { eventHandler: eventHandler }; };
źródło
let obj = MyObject(); elem.someEvent( function(){ obj.func(param) } ); //calls the MyObject.func, passing the param.
źródło