web-dev-qa-db-fra.com

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

Je veux faire un eventHandler qui passe l'événement et quelques paramètres. Le problème est que la fonction ne récupère 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
});

Le "elem" doit être défini en dehors de la fonction anonyme. Comment puis-je obtenir l'élément passé à utiliser dans la fonction anonyme? Y a-t-il un moyen de faire cela?

Et qu'en est-il de addEventListener? Je ne semble pas être capable de passer l'événement via addEventListener du tout

Mettre à jour

J'ai semblé résoudre le problème avec 'ceci'

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

Où cela contient this.element auquel je peux accéder dans la fonction.

Le addEventListener

Mais je m'interroge sur addEventListener:

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

Je ne comprends pas exactement ce que votre code tente 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 de codage exacte, vous pouvez presque toujours faire en sorte qu'une fermeture préserve l'accès aux variables pour vous.

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

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

Vous pouvez ensuite le faire avec une fonction à exécution automatique (IIFE) qui capture les arguments de votre choix dans une fermeture pendant son exécution et renvoie la fonction de gestionnaire d’événements réelle:

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

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

Code enveloppant Javascript dans une fonction anonyme

Expression de fonction immédiatement appelée (IIFE) en JavaScript - Passage de jQuery

Quels sont les bons cas d'utilisation de JavaScript auto-exécutant des fonctions anonymes?

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 transmettez à .bind() seront précédés des arguments que le rappel aura. Donc, vous pouvez 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));
70
jfriend00

Quelque chose que vous pouvez essayer utilise la méthode bind, je pense que cela donne ce que vous demandiez. Si rien d'autre, 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);
9
Knight Yoshi

C'est une vieille question mais une question commune. Alors laissez-moi ajouter celui-ci ici.

Avec la syntaxe ES2015, vous pouvez y parvenir de manière plus succincte:

function event_handler(event, arg) {
  console.log(event, arg);
}

element.addEventListener('click', (event) => event_handler(event, 'Here comes the argument'));
9
SnnSnn

Compte tenu de la mise à jour de la question initiale, il semble y avoir un problème avec le contexte ("ceci") lors de la transmission des gestionnaires d'événements . ici http://www.w3schools.com/js/js_function_invocation.asp

Une version de travail simple de votre exemple pourrait se lire

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 ()?

2
Echsecutor

Réponse courte:

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

... 

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

this à l'intérieur de doThings est l'objet window. Essayez ceci à la place:

var doThings = function (element) {
    var eventHandler = function(ev, func){
        if (element[ev] == undefined) {
            return;
        }

        element[ev] = function(e){
            func(e, element);
        }
    };

    return {
        eventHandler: eventHandler
    };
};
0
jbabey