Как передать аргументы функции прослушивателя addEventListener?
Ситуация несколько похожа на
var someVar = some_other_function();
someObj.addEventListener("click", function(){
some_function(someVar);
}, false);
Проблема в том, что значение someVar
не виден внутри функции слушателя addEventListener
где это, вероятно, рассматривается как новая переменная.
36 ответов
В написанном вами коде нет ничего плохого. И то и другое 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);
Почему бы просто не получить аргументы из целевого атрибута события?
Пример:
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.bind() - для будущих поколений.:)
function some_func(otherFunc, ev) {
// magic happens
}
someObj.addEventListener("click", some_func.bind(null, some_other_func), false);
Просто имейте в виду, что вам нужно настроить функцию слушателя с первым параметром в качестве аргумента, который вы передаете в bind (ваша другая функция), а второй параметр теперь является событием (а не первым, как это было бы),
Довольно старый вопрос, но у меня была такая же проблема сегодня. Самое чистое решение, которое я нашел, - это использовать концепцию карри.
Код для этого:
someObj.addEventListener('click', some_function(someVar));
var some_function = function(someVar) {
return function curried_func(e) {
// do something here
}
}
Называя карри функцию, она позволяет вам вызывать Object.removeEventListener, чтобы отменить регистрацию eventListener в более позднее время выполнения.
Вы можете просто связать все необходимые аргументы с помощью 'bind':
root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));
Таким образом, вы всегда получите event
, arg1
и другие вещи переданы myPrettyHandler
,
http://passy.svbtle.com/partial-application-in-javascript-using-bind
Хорошая альтернатива в одну строку
element.addEventListener('dragstart',(evt) => onDragStart(param1, param2, param3, evt));
function onDragStart(param1, param2, param3, evt) {
//some action...
}
Вы можете добавлять и удалять списки событий с аргументами, объявив функцию как переменную.
myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);
newSrc
метод с параметром myaudio в качестве параметраfuncName
переменная имени функции
Вы можете удалить слушателя с помощью myaudio.removeEventListener('ended',func,false);
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);
Вы можете передать 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)
Вот еще один способ (этот работает внутри для циклов):
var someVar = some_other_function();
someObj.addEventListener("click",
function(theVar){
return function(){some_function(theVar)};
}(someVar),
false);
someVar
значение должно быть доступно только в some_function()
контекст, а не от слушателя. Если вам нравится иметь его внутри слушателя, вы должны сделать что-то вроде:
someObj.addEventListener("click",
function(){
var newVar = someVar;
some_function(someVar);
},
false);
и использовать newVar
вместо.
Другой способ вернуть someVar
значение от some_function()
для дальнейшего использования в слушателе (как новый локальный var):
var someVar = some_function(someVar);
один простой способ выполнить это может быть это
window.addEventListener('click', (e) => functionHandler(e, ...args));
Работает для меня.
Если я не ошибаюсь, используя функцию с 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));
$form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
function save(data, keyword, name, comment, event) {
Вот как я получил событие прошло правильно.
Использование
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);
Отлично работает в моем проекте. Надеюсь, это поможет
Один из способов сделать это с помощью внешней функции:
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));
В 2019 году много изменений api, лучший ответ больше не работает, без исправления ошибки.
поделитесь рабочим кодом.
Вдохновленный всем вышеперечисленным ответом.
button_element = document.getElementById('your-button')
button_element.setAttribute('your-parameter-name',your-parameter-value);
button_element.addEventListener('click', your_function);
function your_function(event)
{
//when click print the parameter value
console.log(event.currentTarget.attributes.your-parameter-name.value;)
}
Для отправки аргументов в функцию обратного вызова 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);
Также попробуйте это (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
Надеюсь нет опечаток:-)
ИДЕАЛЬНОЕ РЕШЕНИЕ для этого - использовать замыкания следующим образом:
Таким образом, в основном вы заключаете функцию в другую функцию и назначаете ее переменной, которую вы можете зарегистрировать как прослушиватель событий, но также и отменить регистрацию!
Я застрял в этом, поскольку использовал его в цикле для поиска элементов и добавления к нему списка. Если вы используете его в цикле, то это будет отлично работать
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);
});
}
Другой обходной путь — использование атрибутов данных .
function func(){
console.log(this.dataset.someVar);
div.removeEventListener("click", func);
}
var div = document.getElementById("some-div");
div.setAttribute("data-some-var", "hello");
div.addEventListener("click", func);
Внутри всех функций есть специальная переменная: arguments. Вы можете передавать свои параметры как анонимные параметры и получать к ним доступ (по порядку) через переменную arguments.
Пример:
var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
some_function(arguments[0]);
}, false);
Поскольку ваш прослушиватель событий - click, вы можете:
someObj.setAttribute("onclick", "function(parameter)");
Я предлагаю вам сделать что-то вроде этого:
var someVar = some_other_function();
someObj.addEventListener("click", (event, param1 = someVar) => {
some_function(param1);
}, false);
Если вы хотите удалить прослушиватель событий позже, хорошей альтернативой будет создание ссылки на каррирующую функцию.
В приведенном ниже коде я проиллюстрирую, что я имею в виду.
// This is the curry function. We return a new function with the signature of what the click-listener expects
const handleClick = (foo, bar) => (clickEvent) => {
console.log('we get our custom input', foo, bar);
console.log('we get the click event too', clickEvent);
}
// We need to store a reference to the listener, making sure we are removing the correct reference later
const myListener = handleClick('foo', 'bar'); // Remember that we now return the actual event-handler
const btn = document.getElementById('btn'); // find the element to attach the listener to
btn.addEventListener('click', myListener);
// remove the event listener like this by using our reference
btn.removeEventListener('click', myListener);
Следующий ответ правильный, но приведенный ниже код не работает в 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 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>
Следующий код работал нормально для меня (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