Comment passer des arguments à la fonction d'écoute addEventListener?

La situation est un peu comme-

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

le problème est que la valeur de someVar n'est pas visible à l'intérieur de la fonction d'écoute du addEventListener , où il est probablement traité comme une nouvelle variable.

213
demandé sur SnareChops 2008-11-02 13:36:14

22 réponses

il n'y a absolument rien de mal avec le code que vous avez écrit. Tant some_function que someVar devraient être accessibles, au cas où ils seraient disponibles dans le contexte où anonyme

function() { some_function(someVar); } 

a été créé.

vérifiez si l'alerte vous donne la valeur que vous cherchiez, assurez-vous qu'elle sera accessible dans la portée de la fonction anonymous (à moins que vous n'ayez plus de code qui opère sur la même variable someVar à côté de la appel à addEventListener )

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);
150
répondu Sergey Ilinsky 2015-01-01 13:09:43

pourquoi ne pas simplement récupérer les arguments de l'attribut cible de l'événement?

exemple:

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 est un langage orienté prototype, rappelez-vous!

235
répondu Zaloz 2014-03-12 06:56:06

cette question Est ancienne mais j'ai pensé offrir une alternative en utilisant ES5.bind() - pour la postérité. :)

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

juste être conscient que vous devez configurer votre fonction d'écoute avec le premier param comme argument que vous passez dans bind (votre autre fonction) et le second param est maintenant l'événement (au lieu du premier, comme il aurait été).

44
répondu Brian Moore 2013-05-16 19:29:20

vous pouvez ajouter et supprimer des event-listeners avec des arguments en déclarant une fonction comme variable.

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

newSrc est la méthode avec myaudio comme paramètre funcName est la variable de nom de fonction

Vous pouvez supprimer l'auditeur avec myaudio.removeEventListener('ended',func,false);

16
répondu Ganesh Krishnan 2012-10-19 07:30:04

question assez vieille mais j'ai eu la même question aujourd'hui. La solution la plus propre que j'ai trouvée est d'utiliser le concept de currying.

le code pour cela:

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

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

en nommant la fonction curried il vous permet d'appeler L'objet.removeEventListener pour désinscrire l'evenlistener à une exécution ultérieure.

12
répondu tomcek112 2018-05-01 19:18:26

vous pouvez passer somevar par la valeur (pas par référence) via une fonctionnalité javascript connue sous le nom de fermeture :

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

ou vous pouvez écrire une fonction wrap commune telle que 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'

ici wrapEventCallback(func,var1,var2) est comme:

func.bind(null, var1,var2)
10
répondu ahui 2018-05-08 08:55:35
La valeur

someVar ne doit être accessible que dans le contexte some_function() , et non dans celui de l'auditeur. Si vous aimez l'avoir dans listener, vous devez faire quelque chose comme:

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

et utiliser newVar à la place.

L'autre façon est de retour someVar valeur some_function() pour l'utiliser plus loin dans l'écoute (comme un nouveau local var):

var someVar = some_function(someVar);
9
répondu Thevs 2008-11-02 14:57:04

Voici encore une autre façon (celle-ci fonctionne à l'intérieur pour les boucles):

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

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

false);
9
répondu Hello World 2015-02-20 16:06:27

vous pouvez simplement lier tous les arguments nécessaires avec 'bind':

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

de cette façon, vous obtiendrez toujours l'événement, arg1, et d'autres choses passées à myPrettyHandler.

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

7
répondu Oleksandr Tkalenko 2018-05-23 09:23:07

Utiliser

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

et si vous voulez passer n'importe quelle valeur personnalisée dans cette fonction anonyme alors la façon la plus facile de le faire est

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

Fonctionne parfaitement dans mon projet. Espérons que cela permettra de

6
répondu kta 2012-10-19 07:30:08

aussi essayer ceux-ci (IE8 + Chrome. Je ne sais pas pour 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

Espoir il n'y a pas de fautes de frappe :-)

3
répondu DMike92 2011-11-20 16:35:28

Une façon est de le faire avec un fonction externe :

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

cette méthode pour envelopper une fonction anonyme entre parenthèses et l'appeler immédiatement est appelée une IIFE (expression de fonction immédiatement invoquée)

vous pouvez vérifier un exemple avec deux paramètres dans 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
répondu Felipe 2015-10-04 05:08:27

fonction.prototype.bind () est la façon de lier une fonction cible à une portée particulière et de définir optionnellement l'objet this dans la fonction cible.

someObj.addEventListener("click", some_function.bind(this), false);

ou pour saisir une partie de la portée lexicale, par exemple dans une boucle:

someObj.addEventListener("click", some_function.bind(this, arg1, arg2), false);

enfin, si le paramètre this n'est pas nécessaire dans la fonction cible:

someObj.addEventListener("click", some_function.bind(null, arg1, arg2), false);
3
répondu eclos 2018-03-11 10:39:04

L'envoi d'arguments à la fonction de rappel d'un eventilistener nécessite la création d'une fonction isolée et la transmission d'arguments à cette fonction isolée.

Voici une jolie petite fonction d'aide que vous pouvez utiliser. Basé sur l'exemple de" hello world " ci-dessus.)

une chose qui est également nécessaire est de maintenir une référence à la fonction afin que nous puissions enlever l'auditeur proprement.

// 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
répondu bob 2015-07-02 22:47:11

j'étais coincé là-dedans car je l'utilisais dans une boucle pour trouver des éléments et y ajouter listner. Si vous l'utilisez en boucle, cela fonctionnera parfaitement

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
répondu Suneel Kumar 2016-02-09 11:24:59
    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
répondu Gennadiy Sherbakha 2015-09-18 06:34:12

L'approche suivante a bien fonctionné pour moi. Modifié de ici .

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
répondu Nate 2016-02-04 22:17:44

la réponse suivante est correcte mais le code ci-dessous ne fonctionne pas dans IE8 si vous supposez que vous avez compressé le fichier js en utilisant yuicompressor. (En fait,encore plus de la NOUS peuples avec IE8)

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

si, nous pouvons corriger la question ci-dessus comme suit et il fonctionne très bien dans tous les navigateurs

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

espérer, il serait utile pour quelqu'un qui comprime le fichier js dans l'environnement de production.

Bonne Chance!!

0
répondu Asik 2014-06-03 15:02:47

il y a une variable spéciale à l'intérieur de toutes les fonctions: arguments . Vous pouvez passer vos paramètres en tant que paramètres anonymes et y accéder (par ordre) à travers la variable arguments .

exemple:

var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
    some_function(arguments[0]);
}, false);
0
répondu StanE 2015-01-12 17:58:34

le code suivant a bien fonctionné pour moi (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);
}

sortie:

0
1
2
0
répondu Šerg 2015-07-15 22:42:42

Vous avez besoin de:

newElem.addEventListener('click', {
    handleEvent: function (event) {
        clickImg(parameter);
    }
});
0
répondu Victor Behar 2018-06-01 18:44:12

autre alternative, peut-être pas aussi élégante que l'utilisation de bind, mais elle est valable pour les événements dans une boucle

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

il a été testé pour Google chrome extensions et peut-être E. la mention srcElement doit être remplacée par E. source dans d'autres navigateurs

j'ai trouvé cette solution en utilisant le commentaire posté par Imatoria mais je ne peux pas le marquer comme utile parce que je n'ai pas assez de réputation :d

-1
répondu fhuertas 2017-05-23 11:47:19