Я хочу создать eventHandler, который передает событие и некоторые параметры. Проблема в том, что функция не получает элемент. Вот пример:
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
});
Elem должен быть определен вне анонимной функции. Как я могу использовать переданный элемент в анонимной функции? Есть ли способ сделать это?
А что насчет addEventListener? Кажется, я вообще не могу передать событие через addEventListener, не так ли?
Обновить
Кажется, я решил проблему с этим
doClick = function(func){
var that = this;
this.element.onclick = function(e){
func(e, that);
}
}
Где это содержит this.element, к которому я могу получить доступ в функции.
AddEventListener
Но меня интересует addEventListener:
function doClick(elem, func){
element.addEventListener('click', func(event, elem), false);
}
javascript
events
event-handling
handler
sebas2day
источник
источник
e.target
/e.currentTarget
?Ответы:
Я не совсем понимаю, что пытается сделать ваш код, но вы можете сделать переменные доступными в любом обработчике событий, используя преимущества закрытия функций:
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); }
В зависимости от конкретной ситуации с кодированием вы почти всегда можете сделать какое-то закрытие, чтобы сохранить доступ к переменным для вас.
Из ваших комментариев, если вы пытаетесь достичь следующего:
element.addEventListener('click', func(event, this.elements[i]))
Затем вы можете сделать это с помощью самоисполняющейся функции (IIFE), которая фиксирует нужные аргументы в закрытии по мере его выполнения и возвращает фактическую функцию обработчика событий:
element.addEventListener('click', (function(passedInElement) { return function(e) {func(e, passedInElement); }; }) (this.elements[i]), false);
Для получения дополнительной информации о том, как работает IIFE, см. Другие ссылки:
Код оболочки Javascript внутри анонимной функции
Выражение немедленно вызываемой функции (IIFE) в JavaScript - передача jQuery
Каковы хорошие варианты использования самоисполняющихся анонимных функций JavaScript?
В этой последней версии, возможно, легче увидеть, что она делает следующим образом:
// 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]));
Также можно использовать
.bind()
для добавления аргументов в обратный вызов. Любые аргументы, которые вы передадите,.bind()
будут добавлены к аргументам, которые будет иметь сам обратный вызов. Итак, вы могли сделать это: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));
источник
element.addEventListener('click', func(event, this.elements[i]))
. Javascript так не работает. Есть и другие способы обойти это, используя замыкания, но вы не можете сделать это так, как написали. addEventListener вызывает его обратный вызов только с одним аргументом (событием), и вы не можете его изменить.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]))
Обратите внимание, что аргумент события всегда стоит последним в аргументах функции и не объявляется явно в методе привязки.Это старый вопрос, но частый. Итак, позвольте мне добавить сюда это.
С синтаксисом стрелочной функции вы можете сделать это более лаконично, поскольку он лексически связан и может быть связан.
Выражение стрелочной функции является синтаксически компактной альтернативой регулярному функциональному выражению, хотя и без собственных привязок к ключевым словам this, arguments, super или new.target.
const event_handler = (event, arg) => console.log(event, arg); el.addEventListener('click', (event) => event_handler(event, 'An argument'));
Если вам нужно очистить прослушиватель событий:
// 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);
Вот сумасшедший однострочник:
// You can replace console.log with some other callback function el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));
Более послушная версия : больше подходит для любой разумной работы.
el.addEventListener('click', (event) => ((arg) => { console.log(event, arg); })('An argument'));
источник
this
и обработчик получил доступ к тому, что ему нужно.Вы можете попробовать использовать метод привязки, я думаю, это достигает того, о чем вы просили. По крайней мере, это все еще очень полезно.
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);
источник
Учитывая обновление исходного вопроса, похоже, что возникла проблема с контекстом ("this") при передаче обработчиков событий. Основы объясняются, например, здесь http://www.w3schools.com/js/js_function_invocation.asp
Простая рабочая версия вашего примера могла бы читать
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);
См. Также Javascript call () и apply () vs bind ()?
источник
Короткий ответ:
x.addEventListener("click", function(e){myfunction(e, param1, param2)}); ... function myfunction(e, param1, param1) { ... }
источник
param1
илиparam2
. Если эти значения изменятся, они не будут установлены на значение, которое они были в то время, когда был создан обработчик событий. Им будет присвоено только текущее значение. Кроме того, это ничем не отличается от установки переменной вне области действия функции прослушивателя событий и ссылки на эту переменную в обработчике событий, поэтому она вообще не выполняет передачу параметров.param1
этоnoodle
первый раз , когда addEventListener называется, и второй раз , когда вы называете,param
этоcheese
то , когда слушатель событияclick
пожаров,param1
будут установленыcheese
и неnoodle
. Следовательно, он не использует «замыкание» для запоминания значения, существовавшего на момент добавления прослушивателя событий. Существуют сценарии, в которых прослушиватель событий должен быть добавлен несколько раз, что не нужно иллюстрировать, чтобы моя точка зрения была верной.this
внутриdoThings
находится оконный объект. Попробуйте вместо этого:var doThings = function (element) { var eventHandler = function(ev, func){ if (element[ev] == undefined) { return; } element[ev] = function(e){ func(e, element); } }; return { eventHandler: eventHandler }; };
источник
let obj = MyObject(); elem.someEvent( function(){ obj.func(param) } ); //calls the MyObject.func, passing the param.
источник