Как передать аргументы функции addEventListener?

Ситуация несколько похожа:

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

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

Ответ 1

В коде, который вы написали, нет абсолютно ничего плохого. Оба some_function и someVar должны быть доступны, если они были доступны в контексте, где анонимный

function() { some_function(someVar); } 

.

Убедитесь, что предупреждение дает вам значение, которое вы искали, убедитесь, что оно будет доступно в области анонимной функции (если у вас больше кода, который работает с той же переменной someVar рядом с вызовом addEventListener)

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

Ответ 2

Почему бы просто не получить аргументы из целевого атрибута события?

Пример:

var someInput = document.querySelector('input');
someInput.addEventListener('click', myFunc, false);
someInput.myParam = 'This is my parameter';
function myFunc(evt)
{
  window.alert( evt.target.myParam );
}

JavaScript - это прототип-ориентированный язык, помните!

Ответ 3

Этот вопрос старый, но я думал, что предлагаю альтернативу, используя ES5.bind() - для потомков.:)

function some_func(otherFunc, ev) {
    // magic happens
}
someObj.addEventListener("click", some_func.bind(null, some_other_func), false);

Просто имейте в виду, что вам нужно настроить свою функцию-слушатель с первым параметром в качестве аргумента, который вы передаете в bind (ваша другая функция), а второй параметр - это событие (вместо первого, так как это будет были).

Ответ 4

Вы можете добавлять и удалять сценарии событий с аргументами, объявляя функцию как переменную.

myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);

newSrc - это метод с параметром myaudio в качестве параметра funcName - это переменная имен функции

Вы можете удалить слушателя с помощью  myaudio.removeEventListener('ended',func,false);

Ответ 5

Довольно старый вопрос, но у меня была такая же проблема сегодня. Самое чистое решение, которое я нашел, - это использовать концепцию карри.

Код для этого:

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

var some_function = function(someVar) {
    return function curried_func(e) {
        // do something here
    }
}

Называя карри функцию, она позволяет вам вызывать Object.removeEventListener, чтобы отменить регистрацию eventListener в более позднее время выполнения.

Ответ 6

Вы можете просто связать все необходимые аргументы с помощью 'bind':

root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));

Таким образом, вы всегда будете получать event, arg1 и другие вещи, передаваемые myPrettyHandler.

http://passy.svbtle.com/partial-application-in-javascript-using-bind

Ответ 7

Вы можете передать somevar по значению (не по ссылке) через функцию JavaScript, известную как закрытие:

var someVar='origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',function(someVar){
   return function(){func(someVar)}
}(someVar));
someVar='changed'

Или вы можете написать обычную функцию обтекания, такую как wrapEventCallback:

function wrapEventCallback(callback){
    var args = Array.prototype.slice.call(arguments, 1);
    return function(e){
        callback.apply(this, args)
    }
}
var someVar='origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',wrapEventCallback(func,someVar))
someVar='changed'

Здесь wrapEventCallback(func,var1,var2) выглядит так:

func.bind(null, var1,var2)

Ответ 8

someVar значение должно быть доступно только в контексте some_function(), а не из прослушивателя. Если вам нравится иметь его внутри слушателя, вы должны сделать что-то вроде:

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

и вместо этого используйте newVar.

Другой способ - вернуть значение someVar из some_function() для дальнейшего использования в listener (как новый локальный var):

var someVar = some_function(someVar);

Ответ 9

Здесь еще один способ (этот работает внутри для циклов):

var someVar = some_other_function();
someObj.addEventListener("click", 

function(theVar){
    return function(){some_function(theVar)};
}(someVar),

false);

Ответ 10

Используйте

   el.addEventListener('click',
    function(){
        // this will give you the id value 
        alert(this.id);    
    },
false);

И если вы хотите передать любое пользовательское значение в эту анонимную функцию, самый простой способ сделать это -

 // this will dynamically create property a property
 // you can create anything like el.<your  variable>
 el.myvalue = "hello world";
 el.addEventListener('click',
    function(){
        //this will show you the myvalue 
        alert(el.myvalue);
        // this will give you the id value 
        alert(this.id);    
    },
false);

Хорошо работает в моем проекте. Надеюсь, это поможет

Ответ 11

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);

Ответ 12

Также попробуйте эти (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

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

Ответ 13

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

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 + '\ meows are: ' + c.meows;
  }
})(cat, catmeows));

Ответ 14

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

Здесь вы можете использовать небольшую вспомогательную функцию. Основано на примере "hello world" выше.)

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

// 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);

Ответ 15

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

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);
     });
}

Ответ 16

    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();

Ответ 17

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

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>

Ответ 18

Если я не ошибаюсь, при вызове функции с 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));

Ответ 19

Следующий ответ верен, но приведенный ниже код не работает в IE8, если вы сжали файл js с помощью yuicompressor. (На самом деле, все еще большинство американских народов, использующих IE8)

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

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

var someVar, eventListnerFunc;
someVar = some_other_function();
eventListnerFunc = some_function(someVar);
someObj.addEventListener("click", eventListnerFunc, false);

Надеюсь, это было бы полезно для кого-то, кто сжимает js файл в рабочей среде.

Удачи!!

Ответ 20

Во всех функциях есть специальная переменная: arguments. Вы можете передавать свои параметры в виде анонимных параметров и обращаться к ним (по порядку) через переменную аргументов.

Пример:

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

Ответ 21

Следующий код работал отлично для меня (firefox):

for (var i=0; i<3; i++) {
   element = new ...   // create your element
   element.counter = i;
   element.addEventListener('click', function(e){
        console.log(this.counter);
        ...            // another code with this element
   }, false);
}

Вывод:

0
1
2

Ответ 22

Тебе нужно:

newElem.addEventListener('click', {
    handleEvent: function (event) {
        clickImg(parameter);
    }
});

Ответ 23

Это решение может хорошо смотреться

var some_other_function = someVar => function() {
}

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

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

Ответ 24

    $form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
    function save(data, keyword, name, comment, event) {

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

Ответ 25

хорошая альтернатива в одну строку

element.addEventListener('dragstart',(evt) => onDragStart(param1, param2, param3, evt));
function onDragStart(param1, param2, param3, evt) {

 //some action...

}

Ответ 26

Вероятно, не оптимально, но просто. Поместите функцию, которая вызывает addEventListener, в свою собственную функцию. Таким образом, любые значения функций, передаваемые в него, сохраняют свою собственную область видимости, и вы можете перебирать эту функцию столько раз, сколько захотите.

Пример Я работал с чтением файла, так как мне нужно было захватить и сделать предварительный просмотр изображения и имени файла. Мне потребовалось некоторое время, чтобы избежать асинхронных проблем при использовании нескольких типов файлов.

    function readFiles(input) {
      if (input.files) {
        for(i=0;i<input.files.length;i++) {

          var filename = input.files[i].name;

          if ( /\.(jpe?g|jpg|png|gif|svg|bmp)$/i.test(filename) ) {
            readFile(input.files[i],filename);
          }
       }
      }
    } //end readFiles



    function readFile(file,filename) {
            var reader = new FileReader();

            reader.addEventListener("load", function() { alert(filename);}, false);

            reader.readAsDataURL(file);

    } //end readFile

Ответ 27

Другая альтернатива, возможно, не такая элегантная, как использование bind, но она действительна для событий в цикле

for (var key in catalog){
    document.getElementById(key).my_id = key
    document.getElementById(key).addEventListener('click', function(e) {
        editorContent.loadCatalogEntry(e.srcElement.my_id)
    }, false);
}

Он был протестирован для расширений google chrome и, возможно, e.srcElement должен быть заменен e.source в других браузерах

Я нашел это решение, используя comment, отправленный Imatoria, но я не могу его пометить как полезный, потому что у меня недостаточно репутации: D