Обработчик событий Javascript с параметрами
Я хочу создать 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 вообще?
Обновление
Кажется, я решил проблему с 'this'
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);
}
Ответы
Ответ 1
Я не совсем понимаю, что пытается сделать ваш код, но вы можете сделать переменные доступными в любом обработчике событий, используя преимущества замыканий функций:
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));
Ответ 2
Это старый вопрос, но общий. Итак, позвольте мне добавить это здесь.
С помощью синтаксиса функции стрелки вы можете добиться этого более кратким способом, поскольку он лексически связан и может быть связан.
Выражение функции со стрелкой является синтаксически компактной альтернативой регулярному выражению функции, хотя и без собственных привязок к ключевым словам this, arguments, super или new.target.
const event_handler = (event, arg) => console.log(event, arg);
el.addEventListener('click', (event) => event_handler(event, 'An argument'));
Если вам нужно очистить слушатель события:
// Let 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'));
Ответ 3
Что-то, что вы можете попробовать, это использовать метод привязки, я думаю, что это достигает того, о чем вы просите. Если ничего другого, это все еще очень полезно.
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);
Ответ 4
Учитывая обновление исходного вопроса, кажется, что проблема связана с контекстом ("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()?
Ответ 5
Короткий ответ:
x.addEventListener("click", function(e){myfunction(e, param1, param2)});
...
function myfunction(e, param1, param1) {
...
}
Ответ 6
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
};
};
Ответ 7
let obj = MyObject();
elem.someEvent( function(){ obj.func(param) } );
//calls the MyObject.func, passing the param.