Функция addEventListener принимает параметры? [Дубликат]

Это случилось со мной, когда я установил Intellij IDEA 2017, перейдите в меню Preferences -> Build, Execution, Deployment -> Debugger и отключите параметр: «Force Classic VM для JDK 1.3.x и ранее». Это работает для меня.

217
задан SnareChops 30 January 2016 в 13:37
поделиться

22 ответа

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

function() { some_function(someVar); } 

.

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

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);
146
ответ дан Tolga Evcimen 23 August 2018 в 06:53
поделиться
  • 1
    Это не работает для цикла. Я всегда получаю последнее значение, а не тот, который принадлежал этой итерации. Любое решение? – iMatoria 25 June 2011 в 18:19
  • 2
    Кто-нибудь знает, почему он не работает в цикле? В чем причина такого поведения? – Morfidon 15 May 2015 в 01:23
  • 3
    @Morfidon, потому что функция с глобальными переменными действует как замыкания в javascript, что означает, что они запоминают среду вне их лексической области. Если вы просто создаете другую функцию в той же среде, то они будут ссылаться на одну и ту же среду. – bugwheels94 20 May 2015 в 15:58
  • 4
    @Morfidon: в цикле значение someVar не является значением, которое оно имело при добавлении слушателя, но значением, которое оно имеет при выполнении слушателя. Когда слушатель выполняется, цикл уже закончился, поэтому значение someVar будет значением, которое оно имело, когда цикл закончился. – www.admiraalit.nl 29 October 2015 в 17:45
  • 5
    @iMatoria Я только что обнаружил, что создание bound function с использованием метода .bind() решит проблему с помощью циклов developer.mozilla.org/en/docs/Web/JavaScript/Reference/… – Luke T O'Brien 22 June 2017 в 09:46

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

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
ответ дан ahui 23 August 2018 в 06:53
поделиться
  • 1
    Большое спасибо за этот ответ! OP не искал этого, но я думаю, что люди, которые печатают «Как передать аргументы addEventListener», в Google будет искать ваш ответ. Мне просто нужно немного больше объяснений :) Я редактирую его. – Sindarus 10 August 2016 в 17:50
  • 2
    Разве это не так, немного, будет событие click? – Suraj Jain 5 May 2018 в 12:57

Следующий ответ верен, но приведенный ниже код не работает в 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
ответ дан Asik 23 August 2018 в 06:53
поделиться

Используйте

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

Прекрасно работает в моем проекте , Надеюсь, это поможет

16
ответ дан BBog 23 August 2018 в 06:53
поделиться

Отправка аргументов функции обратного вызова 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
ответ дан bob 23 August 2018 в 06:53
поделиться
  • 1
    Большое спасибо, добавление / удаление было именно тем, что я искал. – Pic Mickael 27 January 2016 в 19:17

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

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

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

43
ответ дан Brian Moore 23 August 2018 в 06:53
поделиться
  • 1
    Функция.prototype.bind () - действительно лучший способ решить эту проблему. Плюс это работает интуитивно внутри циклов - вы получаете лексический охват, который вы хотите. Нет анонимных функций, IIFEs или специальных свойств, привязанных к объектам. – Clint Pachl 11 March 2018 в 11:14
  • 2
    См. Плюсы и минусы IIFE vs bind () . – Clint Pachl 11 March 2018 в 11:17

Функция.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
ответ дан Clint Pachl 23 August 2018 в 06:53
поделиться

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

224
ответ дан Community 23 August 2018 в 06:53
поделиться
  • 1
    Возвращаясь сюда ... Я хотел бы снова подняться. Благодарю. – Jonatas Walker 28 February 2016 в 14:49
  • 2
    Должен быть отмечен как принятый ответ - самый чистый самый чистый способ сделать это! – Velojet 25 October 2016 в 05:20
  • 3
    Это правильный ответ, потому что он позволяет нам использовать функцию «removeEventListener». – user5260143 4 December 2016 в 13:52
  • 4
    Разве это не должно быть evt.currentTarget.myParam? Если в «someInput» есть еще один элемент, evt.target может относиться к внутреннему элементу. ( jsfiddle.net/qp5zguay/1 [/ д0]) – Herbertusz 24 January 2017 в 20:58
  • 5
    Мне нравится этот ответ лучше всего! Должен быть правильный ответ. – Rob Sobers 11 April 2017 в 19:37

Также попробуйте эти (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
ответ дан DMike92 23 August 2018 в 06:53
поделиться
  • 1
    Как трудно было бы ответить на полный ответ? Должен ли я проверить это на FF? Ну, я не буду беспокоить ... – StefanNch 30 May 2013 в 11:24

Следующий код работал отлично для меня (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
ответ дан Enamul Hassan 23 August 2018 в 06:53
поделиться

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

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

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

Вы можете проверить пример с двумя параметрами в 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
ответ дан Felipe 23 August 2018 в 06:53
поделиться
    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
ответ дан Gennadiy Sherbakha 23 August 2018 в 06:53
поделиться

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

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

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

false);
9
ответ дан Hello World 23 August 2018 в 06:53
поделиться
  • 1
    Это лучший способ. Уродливый, но эффективный внутри циклов, поскольку, отправив аргумент в анонимную функцию, будет захвачен var. – bob 2 July 2015 в 21:45
  • 2
    Это действительно самое лучшее. Отличная работа! – Borna 12 July 2016 в 20:18

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

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

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

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

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

12
ответ дан Matthew Brent 23 August 2018 в 06:53
поделиться
  • 1
    Рад встретиться с этим ответом, говорящим о кардиальной функции. Как бы вы удалили прослушиватель событий? – bob 24 September 2017 в 15:43
  • 2
    Удивительно видеть хорошую терминологию. Вы должны уметь удалить прослушиватель событий, называя функцию curried. Я предлагаю редактирование. – Matthew Brent 1 May 2018 в 15:16

Следующий подход сработал для меня. Модифицировано из здесь .

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
ответ дан Nate 23 August 2018 в 06:53
поделиться

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

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

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

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

5
ответ дан Oleksandr Tkalenko 23 August 2018 в 06:53
поделиться

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

Пример:

var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
    some_function(arguments[0]);
}, false);
-1
ответ дан StanE 23 August 2018 в 06:53
поделиться
  • 1
    Хм ... В чем причина нисходящего? Если бы вы не искали то, что искали, тогда, пожалуйста, объясните более четко, что вы имеете в виду (я знаю, что на вопрос уже был дан ответ). Но не мой код отвечает на то, что вы просили? Специальная переменная "аргументы" дает вам доступ ко всем параметрам внутри функции. – StanE 3 March 2015 в 00:07

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

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
ответ дан Suneel Kumar 23 August 2018 в 06:53
поделиться
Значение

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

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

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

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

var someVar = some_function(someVar);
9
ответ дан Thevs 23 August 2018 в 06:53
поделиться

Вам нужно:

newElem.addEventListener('click', {
    handleEvent: function (event) {
        clickImg(parameter);
    }
});
0
ответ дан Victor Behar 23 August 2018 в 06:53
поделиться

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

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

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

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

16
ответ дан BBog 23 August 2018 в 15:24
поделиться

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

Пример:

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

225
ответ дан Community 23 August 2018 в 15:24
поделиться
  • 1
    Возвращаясь сюда ... Я хотел бы снова подняться. Благодарю. – Jonatas Walker 28 February 2016 в 14:49
  • 2
    Должен быть отмечен как принятый ответ - самый чистый самый чистый способ сделать это! – Velojet 25 October 2016 в 05:20
  • 3
    Это правильный ответ, потому что он позволяет нам использовать функцию «removeEventListener». – user5260143 4 December 2016 в 13:52
  • 4
    Разве это не должно быть evt.currentTarget.myParam? Если в «someInput» есть еще один элемент, evt.target может относиться к внутреннему элементу. ( jsfiddle.net/qp5zguay/1 [/ д0]) – Herbertusz 24 January 2017 в 20:58
  • 5
    Мне нравится этот ответ лучше всего! Должен быть правильный ответ. – Rob Sobers 11 April 2017 в 19:37
  • 6
    – stingMantis 21 April 2017 в 20:10
Другие вопросы по тегам:

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