Как передать аргументы в функцию прослушивателя addEventListener?
ситуация чем-то вроде-
var someVar = some_other_function();
someObj.addEventListener("click", function(){
some_function(someVar);
}, false);
проблема в том, что значение someVar не видно внутри функции прослушивателя addEventListener, где он, вероятно, рассматривается как новая переменная.
22 ответов:
нет абсолютно ничего плохого в коде, который вы написали. Оба
some_functionиsomeVarдолжны быть доступны, в случае, если они были доступны в контексте, где anonymous.function() { some_function(someVar); }проверьте, если предупреждение дает вам значение, которое вы искали, убедитесь, что оно будет доступно в области анонимной функции (если у вас нет больше кода, который работает на том же
someVarпеременная рядом с вызовомaddEventListener)var someVar; someVar = some_other_function(); alert(someVar); someObj.addEventListener("click", function(){ some_function(someVar); }, false);
почему бы просто не получить аргументы из целевого атрибута события?
пример:
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-это прототип-ориентированный язык, помните!
этот вопрос старый, но я думал, что предложу альтернативу, используя ES5.привязать() - для потомков. :)
function some_func(otherFunc, ev) { // magic happens } someObj.addEventListener("click", some_func.bind(null, some_other_func), false);просто имейте в виду, что вам нужно настроить функцию прослушивателя с первым параметром в качестве аргумента, который вы передаете в bind (ваша другая функция), а второй параметр теперь является событием (вместо первого, как это было бы).
вы можете добавлять и удалять eventlisteners с аргументами, объявив функцию в качестве переменной.
myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);
newSrcметод с myaudio в качестве параметраfuncName- имя функции, переменнойвы можете удалить слушателя
myaudio.removeEventListener('ended',func,false);
довольно и старый вопрос, но у меня была та же проблема сегодня. Чистое решение, которое я нашел-это использовать концепцию каррирование.
код:
someObj.addEventListener('click', some_function(someVar)); var some_function = function(someVar) { return function curried_func(e) { // do something here } }называя функцию curried он позволяет вызывать объект.removeEventListener для отмены регистрации eventListener в более позднее время выполнения.
вы можете передать 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)
someVarзначение должно быть доступно только вsome_function()контекста, а не от слушателя. Если вы хотите иметь его в слушателе, вы должны сделать что-то вроде:someObj.addEventListener("click", function(){ var newVar = someVar; some_function(someVar); }, false);и использовать .
другой способ-вернуться
someVarзначениеsome_function()для дальнейшего использования в listener (как новый локальный var):var someVar = some_function(someVar);
вот еще один способ (это работает внутри для циклов):
var someVar = some_other_function(); someObj.addEventListener("click", function(theVar){ return function(){some_function(theVar)}; }(someVar), false);
вы можете просто связать все необходимые аргументы с 'bind':
root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));таким образом, вы всегда будете получать событие, arg1 и другие вещи, переданные myPrettyHandler.
http://passy.svbtle.com/partial-application-in-javascript-using-bind
использовать
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);прекрасно работает в моем проекте. Надеюсь, это поможет
также попробуйте эти (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надеюсь, что нет опечаток :-)
один из способов-сделать это с внешняя функция:
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));
отправка аргументов в функцию обратного вызова 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);
Я застрял в этом, как я использовал его в цикле для поиска элементов и добавления listner к нему. Если вы используете его в цикле, то это будет работать отлично
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); }); }
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();
следующий подход работал хорошо для меня. Изменено с здесь.
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>
следующий ответ правильный, но приведенный ниже код не работает в 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 в производственной среде.
Удачи!!
существует специальная переменная внутри всех функций:аргументы. Вы можете передать свои параметры как анонимные параметры и получить к ним доступ (по порядку) через аргументы переменной.
пример:
var someVar = some_other_function(); someObj.addEventListener("click", function(someVar){ some_function(arguments[0]); }, false);
следующий код работал нормально для меня (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
вам нужно:
newElem.addEventListener('click', { handleEvent: function (event) { clickImg(parameter); } });
другая альтернатива, возможно, не такая элегантная, как использование 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 в других браузерах
Я нашел решение с помощью комментарий сообщение от Imatoria но я не могу отметить его как полезный, потому что у меня недостаточно репутации :D
Comments