Вопрос по javascript, events, event-handling, handler – Javascript обработчик событий с параметрами

63

Я хочу сделать 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
});

«Элем» должен быть определен вне анонимной функции. Как я могу получить переданный элемент для использования в анонимной функции? Есть ли способ сделать это?

А что насчет addEventListener? Кажется, я вообще не могу передать событие через addEventListener?

Update

Кажется, я решил проблему с «этим».

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

Где это содержит this.element, который я могу получить доступ в функции.

The addEventListener

Но мне интересно узнать о addEventListener:

function doClick(elem, func){
    element.addEventListener('click', func(event, elem), false);
}
В вашем вопросе есть элемент, элементы, элемент. Вы можете быть менее запутанным? mihai
Извините, я пытался привести пример своей ситуации, но все пошло не так, я обновил код. sebas2day
Вы бы искалиe.target / e.currentTarget? Rolf
как отправить параметр, если я использую это: ok.addEventListener (& quot; click & quot ;, this.changeText.bind (this)); Alberto Acuña

Ваш Ответ

7   ответов
9

что вы можете попробовать, это использовать метод связывания, я думаю, что это достигнет того, о чем вы просили. Если ничего другого, это все еще очень полезно.

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

let obj = MyObject();

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

//calls the MyObject.func, passing the param.
param также может быть функцией обратного вызова (в глобальном контексте -say) и поэтому может быть легко вызван с запрошенными параметрами.
Как это решает проблему OP?
71

что пытается сделать ваш код, но вы можете сделать переменные доступными в любом обработчике событий, используя преимущества замыканий функций:

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));
Error: User Rate Limit Exceededelement.addEventListener('click', func(event, this.elements[i]))Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded sebas2day
Error: User Rate Limit Exceeded
0

x.addEventListener("click", function(e){myfunction(e, param1, param2)});

... 

function myfunction(e, param1, param1) {
    ... 
} 
2

кажется, что есть проблема с контекстом (& quot; this & quot;) при передаче обработчиков событий. Основы объясняются, например, Вот http://www.w3schools.com/js/js_function_invocation.asp

Простую рабочую версию вашего примера можно прочитать

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

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

Смотрите также Вызов Javascript () & amp; apply () против bind ()?

11

С синтаксисом ES2015 вы можете достичь его более кратким способом:

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

element.addEventListener('click', (event) => event_handler(event, 'Here comes the argument'));
Error: User Rate Limit Exceededvar e = (event) => event_handler(event, 'Here comes the argument'); element.addEventListener('click', e); element.removeEventListener('click', e);
Error: User Rate Limit Exceeded
0

this ВнутриdoThings это объект окна. Попробуйте это вместо:

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

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

    return {
        eventHandler: eventHandler
    };
};

Похожие вопросы