web-dev-qa-db-fra.com

Comment passer un paramètre pour fonctionner en utilisant dans addEventListener?

De manière traditionnelle pour ajouter un écouteur d'événements:

function getComboA(sel) {
    var value = sel.options[sel.selectedIndex].value;  
}

<select id="comboA" onchange="getComboA(this)">
<option value="">Select combo</option>
<option value="Value1">Text1</option>
<option value="Value2">Text2</option>
<option value="Value3">Text3</option>
</select>

Mais je voulais m'adapter à la manière addEventListener:

productLineSelect.addEventListener('change',getSelection(this),false);

function getSelection(sel){
    var value = sel.options[sel.selectedIndex].value;
    alert(value);
}

Cela ne fonctionne pas car je ne peux passer aucun paramètre dans getSelection () comme deuxième paramètre dans la méthode addEventListener? Pour autant que je sache, je ne peux utiliser que le nom de la fonction sans parenthèses.

Une idée?

BTW, veuillez regarder ma question précédente à propos de console.log ne fonctionne pas dans l'inspecteur de développeur safari 6.0, je ne peux écrire aucune sortie dans la console, ce qui est frustrant.

48
mko

Pas besoin de passer quoi que ce soit. La fonction utilisée pour addEventListener aura automatiquement this lié à l'élément courant. Utilisez simplement this dans votre fonction:

productLineSelect.addEventListener('change', getSelection, false);

function getSelection() {
    var value = this.options[this.selectedIndex].value;
    alert(value);
}

Voici le violon: http://jsfiddle.net/dJ4Wm/


Si vous souhaitez transmettre des données arbitraires à la fonction, encapsulez-les dans votre propre appel de fonction anonyme:

productLineSelect.addEventListener('change', function() {
    foo('bar');
}, false);

function foo(message) {
    alert(message);
}

Voici le violon: http://jsfiddle.net/t4Gun/


Si vous souhaitez définir manuellement la valeur de this, vous pouvez utiliser la méthode call pour appeler la fonction:

var self = this;
productLineSelect.addEventListener('change', function() {
    getSelection.call(self);
    // This'll set the `this` value inside of `getSelection` to `self`
}, false);

function getSelection() {
    var value = this.options[this.selectedIndex].value;
    alert(value);
}
102
Joseph Silber

Dans la première ligne de votre code JS:

select.addEventListener('change', getSelection(this), false);

vous appelez getSelection en plaçant (this) derrière la référence de fonction. Ce n'est probablement pas ce que vous voulez, car vous passez maintenant la valeur de retour de cet appel à addEventListener, au lieu d'une référence à la fonction réelle elle-même.


Dans une fonction invoquée par addEventListener, la valeur de this sera automatiquement définie sur l'objet auquel l'écouteur est attaché, productLineSelect dans ce cas.

Si c'est ce que vous voulez, vous pouvez simplement passer la référence de la fonction et this sera dans cet exemple select dans les appels de addEventListener:

select.addEventListener('change', getSelection, false);

Si cela n'est pas ce que vous voulez, vous feriez mieux bind votre valeur pour cela à la fonction que vous passez à addEventListener:

var thisArg = { custom: 'object' };
select.addEventListener('change', getSelection.bind(thisArg), false);

Le .bind part est également un appel, mais cet appel renvoie simplement la même fonction que nous appelons bind on, avec la valeur de this dans la portée de cette fonction corrigé sur thisArg, remplaçant efficacement la nature dynamique de cette liaison.


Pour arriver à votre question réelle: "Comment passer des paramètres pour fonctionner dans addEventListener?"

Vous devez utiliser une définition de fonction supplémentaire:

var globalVar = 'global';

productLineSelect.addEventListener('change', function(event) {
    var localVar = 'local';
    getSelection(event, this, globalVar, localVar);
}, false);

Maintenant, nous passons l'objet d'événement, une référence à la valeur de this à l'intérieur du rappel d'addEventListener, une variable définie et initialisée à l'intérieur de ce rappel, et une variable de l'extérieur de l'appel addEventListener à votre propre getSelection une fonction.


Nous pourrions également avoir à nouveau un objet de notre choix pour être this à l'intérieur du rappel externe:

var thisArg = { custom: 'object' };
var globalVar = 'global';

productLineSelect.addEventListener('change', function(event) {
    var localVar = 'local';
    getSelection(event, this, globalVar, localVar);
}.bind(thisArg), false);
6
Jeffrey Westerkamp

Lorsque vous utilisez addEventListener, this sera lié automatiquement. Donc, si vous voulez une référence à l'élément sur lequel le gestionnaire d'événements est installé, utilisez simplement this depuis votre fonction:

productLineSelect.addEventListener('change',getSelection,false);

function getSelection(){
    var value = sel.options[this.selectedIndex].value;
    alert(value);
}

Si vous voulez passer un autre argument du contexte où vous appelez addEventListener, vous pouvez utiliser une fermeture, comme ceci:

productLineSelect.addEventListener('change', function(){ 
    // pass in `this` (the element), and someOtherVar
    getSelection(this, someOtherVar); 
},false);

function getSelection(sel, someOtherVar){
    var value = sel.options[sel.selectedIndex].value;
    alert(value);
    alert(someOtherVar);
}
5
Lee

Si la valeur this que vous voulez est juste l'objet auquel vous avez lié le gestionnaire d'événements, alors addEventListener() le fait déjà pour vous. Lorsque vous faites cela:

productLineSelect.addEventListener('change', getSelection, false);

la fonction getSelection sera déjà appelée avec this définie sur l'objet auquel le gestionnaire d'événements était lié. Il sera également passé un argument qui représente l'objet d'événement qui a toutes sortes d'informations d'objet sur l'événement.

function getSelection(event) {
    // this will be set to the object that the event handler was bound to
    // event is all the detailed information about the event
}

Si la valeur this souhaitée est une autre valeur que l'objet auquel vous avez lié le gestionnaire d'événements, vous pouvez simplement faire ceci:

var self = this;
productLineSelect.addEventListener('change',function() {
    getSelection(self)
},false);

En guise d'explication:

  1. Vous enregistrez la valeur de this dans une variable locale dans votre autre gestionnaire d'événements.
  2. Vous créez ensuite une fonction anonyme pour passer addEventListener.
  3. Dans cette fonction anonyme, vous appelez votre fonction réelle et lui transmettez la valeur enregistrée de this.
2
jfriend00