web-dev-qa-db-fra.com

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 dans la fonction d'écoute de addEventListener, où elle est probablement traitée comme une nouvelle variable.

226
Abhishek Yadav

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

function() { some_function(someVar); } 

a été créé. 

Vérifiez si l'alerte vous donne la valeur recherchée, assurez-vous qu'elle sera accessible dans le cadre de la fonction anonyme (sauf si vous avez plus de code qui fonctionne sur la même variable someVar à côté de l'appel à addEventListener

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

Pourquoi ne pas simplement obtenir 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!

264
Zaloz

Cette question est ancienne, mais je pensais proposer une alternative en utilisant .bind () de ES5 - pour la postérité. :)

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

Sachez simplement que vous devez configurer votre fonction d’audience avec le premier paramètre comme argument que vous passez à bind (votre autre fonction) et que le second paramètre est maintenant l’événement (au lieu du premier, comme il aurait été). .

46
Brian Moore

Vous pouvez ajouter et supprimer des eventlisteners avec des arguments en déclarant une fonction en tant que variable.

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

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

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

18
Ganesh Krishnan

Une question assez ancienne, mais j'avais le même problème 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, cela vous permet d’appeler Object.removeEventListener pour annuler l’enregistrement de eventListener à une heure d’exécution ultérieure.

16
tomcek112

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 la event, arg1 et d'autres éléments transmis à myPrettyHandler.

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

11
Oleksandr Tkalenko

Vous pouvez passer certaines valeurs par valeur (et non par référence) via une fonctionnalité javascript appelée fermeture :

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

Ou vous pourriez écrire une fonction de bouclage 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
ahuigo

La valeur someVar devrait être accessible uniquement dans le contexte some_function(), et non à partir du nom de l'auditeur . Si vous souhaitez l'afficher dans l'écouteur, vous devez effectuer les opérations suivantes:

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

et utilisez newVar à la place.

L’autre méthode consiste à renvoyer la valeur someVar de some_function() pour l’utiliser plus avant dans le programme d’écoute (en tant que nouvelle variable locale):

var someVar = some_function(someVar);
9
Thevs

Voici encore un autre moyen (celui-ci fonctionne à l'intérieur des boucles):

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

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

false);
9
Hello World

Utilisation 

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

Et si vous souhaitez transmettre une valeur personnalisée à cette fonction anonyme, le moyen le plus simple 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. J'espère que cela aidera

6
kta

Function.prototype.bind () est le moyen de lier une fonction cible à une étendue particulière et éventuellement de définir l'objet this dans la fonction cible.

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

Ou pour capturer 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
eclos

Essayez aussi 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

J'espère qu'il n'y a pas de fautes de frappe :-)

3
DMike92

Une façon de le faire est d'utiliser une fonction outer:

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

Cette méthode permettant de placer une fonction anonyme entre parenthèses et de l'appeler immédiatement est appelée une IIFE (expression de fonction appelée immédiatement)

Vous pouvez consulter 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
Felipe

J'étais coincé dans cette tâche car je l'utilisais dans une boucle pour trouver des éléments et y ajouter un programme d'écoute. 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
Suneel Kumar

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

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

Une chose est également nécessaire est de maintenir une référence à la fonction afin que nous puissions supprimer 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
bob

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
Nate
    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

Si je ne me trompe pas, appeler la fonction avec bind crée effectivement une nouvelle fonction qui est renvoyée par la méthode bind. Cela vous causera des problèmes plus tard ou si vous souhaitez supprimer l'écouteur d'événements, car il s'agit essentiellement d'une fonction anonyme:

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

Alors prenez cela en compte.

Si vous utilisez ES6, vous pouvez faire la même chose que suggéré mais un peu plus propre:

someObject.addEventListener('event', () => myCallback(params));
1
developer82

Vous avez besoin:

newElem.addEventListener('click', {
    handleEvent: function (event) {
        clickImg(parameter);
    }
});
0
Victor Behar

Belle alternative à une ligne

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

 //some action...

}
0
Gon82

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
Šerg
    $form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
    function save(data, keyword, name, comment, event) {

C'est comme ça que j'ai fait passer l'événement correctement.

0
chovy

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 avec yuicompressor. (En fait, la plupart des Américains utilisent encore IE8)

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

Donc, nous pouvons résoudre le problème ci-dessus comme suit et cela fonctionne très bien dans tous les navigateurs

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

J'espère que cela serait utile pour quelqu'un qui compresse le fichier js dans un environnement de production.

Bonne chance!!

0
Asik

Probablement pas optimal, mais assez simple pour ceux qui ne sont pas très avertis. Mettez la fonction qui appelle addEventListener dans sa propre fonction. Ainsi, toutes les valeurs de fonction qui y sont passées conservent leur propre portée et vous pouvez effectuer une itération sur cette fonction autant de fois que vous le souhaitez.

Exemple J'ai travaillé avec la lecture de fichier car j'avais besoin de capturer et de rendre un aperçu de l'image et du nom de fichier. Il m'a fallu un certain temps pour éviter les problèmes asynchrones lors de l'utilisation d'un type de téléchargement de plusieurs fichiers. Je verrais accidentellement le même 'nom' sur tous les rendus malgré le téléchargement de différents fichiers.

À l'origine, toute la fonction readFile () faisait partie de la fonction readFiles (). Cela provoquait des problèmes de portée asynchrones.

    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
Spoo

Cette solution peut être intéressante

var some_other_function = someVar => function() {
}

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

ou lier des variables sera également bon

0
fnclovers

Il y a une variable spéciale dans toutes les fonctions: arguments. Vous pouvez passer vos paramètres sous forme de paramètres anonymes et y accéder (par ordre) via la variable arguments.

Exemple:

var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
    some_function(arguments[0]);
}, false);
0
StanE