127 votes

Gestionnaire d'événements Javascript avec paramètres

Je veux faire un eventHandler qui transmet l'événement et certains paramètres. Le problème est que la fonction ne reçoit pas l'élément. Voici un exemple :

doClick = function(func){
    var elem = .. // the element where it is all about
    elem.onclick = function(e){
        func(e, elem);
    }
}
doClick(function(e, element){
    // do stuff with element and the event
});

En elem doit être définie en dehors de la fonction anonyme. Comment puis-je obtenir l'élément passé pour l'utiliser dans la fonction anonyme ? Existe-t-il un moyen de le faire ?

Et qu'en est-il des addEventListener ? Je ne semble pas être en mesure de passer l'événement par le biais d'un addEventListener Je ne suis pas du tout d'accord ?

Mise à jour

Il semble que j'aie résolu le problème avec "ceci

doClick = function(func){
    var that = this;
    this.element.onclick = function(e){
        func(e, that);
    }
}

Où cela se trouve this.element à laquelle je peux accéder dans la fonction.

La fonction addEventListener

Mais je m'interroge sur la addEventListener :

function doClick(elem, func){
    element.addEventListener('click', func(event, elem), false);
}

136voto

jfriend00 Points 152127

Je ne comprends pas exactement ce que votre code essaie de faire, mais vous pouvez rendre les variables disponibles dans n'importe quel gestionnaire d'événements en utilisant les avantages des fermetures de fonctions :

function addClickHandler(elem, arg1, arg2) {
    elem.addEventListener('click', function(e) {
        // in the event handler function here, you can directly refer
        // to arg1 and arg2 from the parent function arguments
    }, false);
}

En fonction de votre situation exacte en matière de codage, vous pouvez presque toujours faire en sorte qu'une sorte de fermeture préserve l'accès aux variables pour vous.

D'après vos commentaires, si ce que vous essayez d'accomplir est ceci :

element.addEventListener('click', func(event, this.elements[i]))

Vous pouvez alors utiliser une fonction auto-exécutoire (IIFE) qui capture les arguments que vous souhaitez dans une fermeture pendant qu'elle s'exécute et renvoie la fonction de gestion de l'événement :

element.addEventListener('click', (function(passedInElement) {
    return function(e) {func(e, passedInElement); };
}) (this.elements[i]), false);

Pour plus d'informations sur le fonctionnement d'une IIFE, voir ces autres références :

Code Javascript à l'intérieur d'une fonction anonyme

Expression de fonction immédiatement invoquée (IIFE) en JavaScript - Passer jQuery

Quels sont les bons cas d'utilisation des fonctions anonymes auto-exécutées en JavaScript ?

Cette dernière version est peut-être plus facile à comprendre :

// return our event handler while capturing an argument in the closure
function handleEvent(passedInElement) {
    return function(e) {
        func(e, passedInElement); 
    };
}

element.addEventListener('click', handleEvent(this.elements[i]));

Il est également possible d'utiliser .bind() pour ajouter des arguments à un rappel. Tous les arguments que vous passez à .bind() sera ajouté aux arguments que le callback lui-même aura. Ainsi, vous pourriez faire ceci :

elem.addEventListener('click', function(a1, a2, e) {
    // inside the event handler, you have access to both your arguments
    // and the event object that the event handler passes
}.bind(elem, arg1, arg2));

58voto

snnsnn Points 81

La question est ancienne mais fréquente. Permettez-moi donc de l'ajouter ici.

Avec syntaxe de la fonction flèche vous pouvez l'obtenir de manière plus succincte puisqu'il est lié lexicalement et peut être enchaîné.

Une expression de fonction fléchée est une alternative syntaxiquement compacte à une expression de fonction régulière, bien qu'elle ne dispose pas de ses propres liens avec les mots-clés this, arguments, super ou new.target.

const event_handler = (event, arg) => console.log(event, arg);
el.addEventListener('click', (event) => event_handler(event, 'An argument'));

Si vous devez nettoyer l'écouteur d'événements :

// Let's use use good old function sytax
function event_handler(event, arg) {
  console.log(event, arg);
}

// Assign the listener callback to a variable
var doClick = (event) => event_handler(event, 'An argument'); 

el.addEventListener('click', doClick);

// Do some work...

// Then later in the code, clean up
el.removeEventListener('click', doClick);

Voici une phrase folle :

// You can replace console.log with some other callback function
el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));

Version plus docile : Plus approprié pour tout travail sain.

el.addEventListener('click', (event) => ((arg) => {
  console.log(event, arg);
})('An argument'));

11voto

Knight Yoshi Points 496

Vous pouvez essayer d'utiliser la méthode de liaison, je pense qu'elle permet d'atteindre l'objectif que vous vous êtes fixé. A défaut d'autre chose, c'est toujours très utile.

function doClick(elem, func) {
  var diffElem = document.getElementById('some_element'); //could be the same or different element than the element in the doClick argument
  diffElem.addEventListener('click', func.bind(diffElem, elem))
}

function clickEvent(elem, evt) {
  console.log(this);
  console.log(elem); 
  // 'this' and elem can be the same thing if the first parameter 
  // of the bind method is the element the event is being attached to from the argument passed to doClick
  console.log(evt);
}

var elem = document.getElementById('elem_to_do_stuff_with');
doClick(elem, clickEvent);

2voto

Echsecutor Points 111

Compte tenu de la mise à jour de la question initiale, il semble qu'il y ait un problème avec le contexte ("this") lors du passage des gestionnaires d'événements. Les principes de base sont expliqués, par exemple, ici http://www.w3schools.com/js/js_function_invocation.asp

Une version simple et fonctionnelle de votre exemple pourrait être la suivante

var doClick = function(event, additionalParameter){
    // do stuff with event and this being the triggering event and caller
}

element.addEventListener('click', function(event)
{
  var additionalParameter = ...;
  doClick.call(this, event, additionalParameter );
}, false);

Voir aussi Javascript call() & apply() vs bind() ?

2voto

user3093134 Points 29

Réponse courte :

x.addEventListener("click", function(e){myfunction(e, param1, param2)});

... 

function myfunction(e, param1, param1) {
    ... 
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X