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 pas obtenir 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 de l'élément passé à utiliser dans la fonction anonyme? Est-il un moyen de faire cela?

et addEventListener? Je ne semble pas être en mesure de passer l'événement par un addEventListener à tous les faire-je ?

mise à Jour

, je semble résoudre le problème avec cette

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

où ceci contient ceci.élément auquel je peux accéder dans la fonction.

addEventListener

mais je m'interroge sur le addEventListener:

function doClick(elem, func){
    element.addEventListener('click', func(event, elem), false);
}
56
demandé sur sebas2day 2012-04-03 23:32:36

6 réponses

Je ne comprends pas exactement ce que votre code essaie de faire, mais vous pouvez rendre les variables disponibles dans n'importe quel handler d'événement 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);
}

selon votre situation exacte de codage, vous pouvez presque toujours faire une sorte de fermeture préserver l'accès aux variables pour vous.

de vos commentaires, si ce que vous essayez d'accomplir est ceci:

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

alors, vous pourrait le faire avec une fonction d'auto-exécution (IIFE) qui capture les arguments que vous voulez dans une fermeture pendant qu'elle exécute et retourne la fonction de gestionnaire d'événements:

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

pour plus d'informations sur le fonctionnement D'une vie, voir ces autres références:

code D'emballage Javascript à l'intérieur de la fonction anonyme

expression de fonction immédiatement invoquée (IIFE) en JavaScript-Passing jQuery

Qu'est-ce qu'un bon cas D'utilisation de JavaScript pour exécuter automatiquement des fonctions anonymes?

cette dernière version est peut-être plus facile de voir ce qu'elle fait comme ceci:

// 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() seront précédés des arguments que le rappel devra lui-même. Donc, 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));
67
répondu jfriend00 2018-01-24 16:17:53

quelque chose que vous pouvez essayer est d'utiliser la méthode bind, je pense que cela permet d'atteindre 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);
8
répondu Knight Yoshi 2015-01-05 13:54:51

c'est une question ancienne mais commune. Alors, permettez-moi d'ajouter ici.

avec la syntaxe ES2015 vous pouvez le réaliser 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'));
4
répondu SnnSnn 2018-02-27 18:49:36

étant donné la mise à jour de la question originale, il semble qu'il y ait des problèmes avec le contexte ("ceci") en passant les gestionnaires d'événements. Les bases sont expliquées ici http://www.w3schools.com/js/js_function_invocation.asp

une version 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 appel Javascript () & apply () vs bind ()?

2
répondu Echsecutor 2017-05-23 12:03:05

this à l'intérieur doThings est l'objet de la fenêtre. Essayez plutôt ceci:

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
répondu jbabey 2012-04-03 19:50:19
let obj = MyObject();

elem.someEvent( function(){ obj.func(param) } );

//calls the MyObject.func, passing the param.
-2
répondu Δημήτρης Βουζουναράς 2016-11-16 13:54:13