Как передать аргументы функции прослушивателя addEventListener? - PullRequest
238 голосов
/ 02 ноября 2008

Ситуация чем-то напоминает -

var someVar = some_other_function();
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);

Проблема в том, что значение someVar не отображается внутри функции прослушивателя addEventListener, где оно, вероятно, рассматривается как новая переменная.

Ответы [ 27 ]

6 голосов
/ 04 февраля 2014

Function.prototype.bind () - это способ привязки целевой функции к определенной области и, при необходимости, определения объекта this в целевой функции.

someObj.addEventListener("click", some_function.bind(this), false);

Или для захвата некоторой лексической области видимости, например, в цикле:

someObj.addEventListener("click", some_function.bind(this, arg1, arg2), false);

Наконец, если параметр this не требуется в целевой функции:

someObj.addEventListener("click", some_function.bind(null, arg1, arg2), false);
3 голосов
/ 04 октября 2015

Один способ сделать это с внешней функцией :

elem.addEventListener('click', (function(numCopy) {
  return function() {
    alert(numCopy)
  };
})(num));

Этот метод оборачивания анонимной функции в круглые скобки и немедленного ее вызова называется IIFE (выражение для немедленного вызова функции)

Вы можете проверить пример с двумя параметрами в http://codepen.io/froucher/pen/BoWwgz.

catimg.addEventListener('click', (function(c, i){
  return function() {
    c.meows++;
    i.textContent = c.name + '\'s meows are: ' + c.meows;
  }
})(cat, catmeows));
3 голосов
/ 03 июля 2015

Для отправки аргументов в функцию обратного вызова eventListener необходимо создать изолированную функцию и передать аргументы этой изолированной функции.

Вот хорошая маленькая вспомогательная функция, которую вы можете использовать. На основе приведенного выше примера "Привет, мир".)

Также необходимо сохранить ссылку на функцию, чтобы мы могли аккуратно удалить слушателя.

// Lambda closure chaos.
//
// Send an anonymous function to the listener, but execute it immediately.
// This will cause the arguments are captured, which is useful when running 
// within loops.
//
// The anonymous function returns a closure, that will be executed when 
// the event triggers. And since the arguments were captured, any vars 
// that were sent in will be unique to the function.

function addListenerWithArgs(elem, evt, func, vars){
    var f = function(ff, vv){
            return (function (){
                ff(vv);
            });
    }(func, vars);

    elem.addEventListener(evt, f);

    return f;
}

// Usage:

function doSomething(withThis){
    console.log("withThis", withThis);
}

// Capture the function so we can remove it later.
var storeFunc = addListenerWithArgs(someElem, "click", doSomething, "foo");

// To remove the listener, use the normal routine:
someElem.removeEventListener("click", storeFunc);
3 голосов
/ 20 ноября 2011

Также попробуйте это (IE8 + Chrome. Я не знаю для FF):

function addEvent(obj, type, fn) {
    eval('obj.on'+type+'=fn');
}

function removeEvent(obj, type) {
    eval('obj.on'+type+'=null');
}

// Use :

function someFunction (someArg) {alert(someArg);}

var object=document.getElementById('somObject_id') ;
var someArg="Hi there !";
var func=function(){someFunction (someArg)};

// mouseover is inactive
addEvent (object, 'mouseover', func);
// mouseover is now active
addEvent (object, 'mouseover');
// mouseover is inactive

Надеюсь, что нет опечаток: -)

2 голосов
/ 22 января 2019

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

// Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', myCallback);
someObject.removeEventListener('event', myCallback);

// Not Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', function() { myCallback });
someObject.removeEventListener('event', /* can't remove anonymous function */);

Так что имейте это в виду.

Если вы используете ES6, вы можете сделать то же самое, что предложено, но немного чище:

someObject.addEventListener('event', () => myCallback(params));
2 голосов
/ 09 февраля 2016

Я застрял в этом, поскольку использовал его в цикле для поиска элементов и добавления к нему списка. Если вы используете его в цикле, то это будет прекрасно работать

for (var i = 0; i < states_array.length; i++) {
     var link = document.getElementById('apply_'+states_array[i].state_id);
     link.my_id = i;
     link.addEventListener('click', function(e) {   
        alert(e.target.my_id);        
        some_function(states_array[e.target.my_id].css_url);
     });
}
1 голос
/ 05 февраля 2016

Следующий подход хорошо сработал для меня. Изменено с здесь .

function callback(theVar) {
  return function() {
    theVar();
  }
}

function some_other_function() {
  document.body.innerHTML += "made it.";
}

var someVar = some_other_function;
document.getElementById('button').addEventListener('click', callback(someVar));
<!DOCTYPE html>
<html>
  <body>
    <button type="button" id="button">Click Me!</button>
  </body>
</html>
1 голос
/ 18 сентября 2015
    var EV = {
        ev: '',
        fn: '',
        elem: '',
        add: function () {
            this.elem.addEventListener(this.ev, this.fn, false);
        }
    };

    function cons() {
        console.log('some what');
    }

    EV.ev = 'click';
    EV.fn = cons;
    EV.elem = document.getElementById('body');
    EV.add();

//If you want to add one more listener for load event then simply add this two lines of code:

    EV.ev = 'load';
    EV.add();
0 голосов
/ 17 февраля 2019
    $form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
    function save(data, keyword, name, comment, event) {

Вот как я правильно прошел событие.

0 голосов
/ 06 ноября 2018

Это решение может хорошо выглядеть

var some_other_function = someVar => function() {
}

someObj.addEventListener('click', some_other_function(someVar));

или связные валидные тоже будут хороши

...