Je veux créer un eventHandler qui transmet l'événement et certains paramètres. Le problème est que la fonction n'obtient 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
});
L'élément doit être défini en dehors de la fonction anonyme. Comment puis-je utiliser l'élément passé dans la fonction anonyme? Y a-t-il un moyen de faire cela?
Et qu'en est-il de addEventListener? Je ne semble pas du tout capable de transmettre l'événement via un addEventListener, n'est-ce pas?
Mise à 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 cet élément 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);
}
javascript
events
event-handling
handler
sebas2day
la source
la source
e.target
/e.currentTarget
?Réponses:
Je ne comprends pas exactement ce que votre code essaie de faire, mais vous pouvez rendre des 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 à peu près toujours faire une sorte de fermeture pour préserver 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]))
Ensuite, vous pouvez le faire avec une fonction auto-exécutable (IIFE) qui capture les arguments souhaités dans une fermeture lors de 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, consultez ces autres références:
Code d'emballage Javascript dans une fonction anonyme
Expression de fonction immédiatement invoquée (IIFE) dans JavaScript - Passer jQuery
Quels sont les bons cas d'utilisation des fonctions anonymes auto-exécutables JavaScript?
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 de l'utiliser
.bind()
pour ajouter des arguments à un rappel. Tous les arguments que vous passez.bind()
seront ajoutés aux arguments que le rappel lui-même 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));
la source
element.addEventListener('click', func(event, this.elements[i]))
. Javascript ne fonctionne tout simplement pas de cette façon. Il existe d'autres moyens de contourner cela, en utilisant des fermetures, mais vous ne pouvez pas le faire comme vous l'avez écrit. addEventListener appelle son callback avec exactement un argument (l'événement) et vous ne pouvez en aucun cas changer cela.function eventFunction (arg, evt) { console.log(arg[0],arg[1],arg[2]) console.log(evt) } var el = document.getElementById('elementID'); el.addEventListener('click', eventFunction.bind(el,[1,2,3]))
Notez que l'argument d'événement est toujours le dernier dans les arguments de la fonction, et n'est pas explicitement déclaré dans la méthode de liaison.C'est une question ancienne mais courante. Alors laissez-moi ajouter celui-ci ici.
Avec la syntaxe de la fonction flèche, vous pouvez y parvenir de manière plus succincte car elle est liée lexicalement et peut être chaînée.
Une expression de fonction de flèche est une alternative syntaxiquement compacte à une expression de fonction régulière, bien que sans ses propres liaisons aux 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 un one-liner fou:
// 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ée pour tout travail sensé.
el.addEventListener('click', (event) => ((arg) => { console.log(event, arg); })('An argument'));
la source
this
et le gestionnaire a pu accéder à ce dont il a besoin.Quelque chose que vous pouvez essayer est d'utiliser la méthode bind, je pense que cela répond à vos attentes. 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);
la source
Compte tenu de la mise à jour de la question d'origine, il semble qu'il y ait un problème avec le contexte ("this") lors du passage des gestionnaires d'événements. Les bases sont expliquées par exemple ici http://www.w3schools.com/js/js_function_invocation.asp
Une version de travail simple de votre exemple pourrait 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 ()?
la source
Réponse courte:
x.addEventListener("click", function(e){myfunction(e, param1, param2)}); ... function myfunction(e, param1, param1) { ... }
la source
param1
ouparam2
. Si ces valeurs changent, elles ne seront pas définies sur la valeur qu'elles étaient au moment de la création du gestionnaire d'événements. Ils seront définis uniquement sur la valeur actuelle. En outre, cela n'est pas différent de définir une variable en dehors de la portée de la fonction d'écoute d'événements et de référencer cette variable dans le gestionnaire d'événements, de sorte qu'il n'accomplit pas du tout la transmission de paramètres.param1
c'estnoodle
la première fois que l'addEventListener est appelé, et la deuxième fois que vous l'appelez,param
c'est àcheese
chaque fois que l'écouteur d'événement seclick
déclenche,param1
sera défini surcheese
et nonnoodle
. Par conséquent, il n'utilise pas de «fermeture» pour se souvenir de la valeur qui existait au moment de l'ajout de l'écouteur d'événements. Il existe des scénarios dans lesquels l'écouteur d'événements doit être ajouté plusieurs fois, ce qui n'a pas besoin d'être illustré pour que mon point soit valide.this
à l'intérieur sedoThings
trouve l'objet window. 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 }; };
la source
let obj = MyObject(); elem.someEvent( function(){ obj.func(param) } ); //calls the MyObject.func, passing the param.
la source