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

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

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

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

+231
источник поделиться
27 ответов

В коде, который вы написали, нет абсолютно ничего плохого. Оба 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);
+173
источник

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

Пример:

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 - это прототип-ориентированный язык, помните!

+276
источник
другие ответы

Связанные вопросы


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

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

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

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

+49
источник

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

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

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

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

+19
источник

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

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

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

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

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

+16
источник

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

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

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

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

+12
источник

Вы можете передать 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)
+10
источник

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);
+9
источник

Используйте

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

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

+7
источник

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);
+4
источник

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

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

+3
источник

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

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));
+3
источник

Отправка аргументов функции обратного вызова 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);
+2
источник

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

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);
     });
}
+2
источник
    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();
+1
источник

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

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
источник

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

Следующий ответ верен, но приведенный ниже код не работает в 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 файл в рабочей среде.

Удачи!!

0
источник

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

Пример:

var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
    some_function(arguments[0]);
}, false);
0
источник

Следующий код работал отлично для меня (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
0
источник

Тебе нужно:

newElem.addEventListener('click', {
    handleEvent: function (event) {
        clickImg(parameter);
    }
});
0
источник

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

var some_other_function = someVar => function() {
}

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

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

0
источник
    $form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
    function save(data, keyword, name, comment, event) {

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

0
источник

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

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

 //some action...

}
0
источник

Вероятно, не оптимально, но просто. Поместите функцию, которая вызывает 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
0
источник

Другая альтернатива, возможно, не такая элегантная, как использование 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

-1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос