3

J'ai cherché avant les messages SO here, here et here, et ne pouvait pas une réponse qui avait un sens pour moi. Cela devrait être une question fondamentale, mais je ne comprends pas les messages que je trouve. Ils ne semblent pas utiliser un ce paramètre.Attacher un objet onchange à une fermeture?

Je veux ajouter programatically une entrée avec un événement onchange, de sorte que le résultat final est le suivant:

<input type="button" onchange="handleButtonOnChange(this)">ClickMe</input> 

Je travaille sur un projet qui utilise un navigateur IE6 embarqué dans une ancienne application Delphi, donc je dois avoir une solution IE6 compatible (oui, IE6 est horrible, mais il y a des raisons pour lesquelles je suis coincé pour le moment).

Ma première tentative était la suivante:

var DaySelect = document.createElement("select"); 
DaySelect.id = ParentID+"-day"; 
DaySelect.disabled = true; 
MonthSelect.onchange="handleDayChange(this);" //<--- not correct 
Parent.appendChild(DaySelect); 

Je lis alors que le .onchange doit être attribué un objet, pas une chaîne, et on doit utiliser à la place:

MonthSelect.onchange=handleDayChange; //<--- '(this)' removed 

Mais me semble que cela se traduira par cet élément (notez le absent ce paramètre)

<input type="button" onchange="handleButtonOnChange">ClickMe</input> 

Si j'utilise la ligne ci-dessous, à la place, cela ne fera-t-il pas de fermeture, et le 'this' se référera à l'événement au moment où l'objet est assigné à la propriété .onchange, au lieu d'être l'événement de l'événement de changement? Je suis un programmeur Web relativement nouveau, mais un programmeur Delphi de longue date. Les fermetures me font toujours mal à la tête. J'apprécie toute aide dans ce domaine.

En outre, j'ai lu here sur l'utilisation de addEventListener et les problèmes avec les versions plus anciennes d'IE, et le dernier message sur la page fournit un contourner. Mais je ne comprends pas comment ça fonctionne.

EDIT - Et qu'en est-il de passer d'autres paramètres? Il semble que de nombreux gestionnaires d'événements auront besoin de paramètres spécifiques pour l'élément attaché. Il semble qu'il n'est tout simplement pas possible d'ajouter un écouteur avec des paramètres.

+1

Est-ce que "this" pointe vers l'élément d'entrée dans votre exemple? – Trey

+0

Je souhaite pouvoir utiliser plusieurs éléments avec le même gestionnaire javascript. Donc, ma pensée était que le gestionnaire aurait besoin de passer l'élément qui a créé l'événement. Alors oui, le 'ceci' serait l'élément qui a initié l'appel. – kdtop

+1

Dans votre dernière question de code/commentaire, 'this' fait référence à l'objet global' window' (s'il est appelé depuis le contexte global js). Toujours dans cette ligne de code, vous affectez à la propriété la valeur de retour de la fonction, pas la fonction elle-même. Vous appelez la fonction là-bas. –

Répondre

1

Une fermeture simple si vous créez les éléments de JS comme vous montrer:

var DaySelect = document.createElement("select"); 
DaySelect.id = ParentID+"-day"; 
DaySelect.disabled = true; 
MonthSelect.onchange=function(){handleDayChange(DaySelect);}; 
Parent.appendChild(DaySelect); 

Puisque la fonction est créée à l'intérieur du champ d'application que vous créez l'élément, les mêmes variables seront disponibles à elle.

EDIT:

paramètres supplémentaires peuvent être passés avec cette méthode, par exemple, la fonction anonyme nous créons et joindre en tant que gestionnaire aura encore l'objet d'événement qui lui est envoyé:

function(e){handleDayChange(DaySelect, e);};

Dans l'objet événement, vous aurez accès à la cible de l'événement, mais dans votre exemple, la cible de l'événement et "this" ne sont pas le même élément, donc le gestionnaire n'a aucun moyen de connaître l'élément DaySelect.JQuery rend la gestion des événements beaucoup plus simple, ce qui est l'une des raisons pour lesquelles beaucoup de gens l'utilisent, il normalise aussi ses méthodes entre différents navigateurs, donc vous n'avez pas besoin d'écrire plusieurs versions du même code (dans la plupart des cas

+0

Je vais essayer et poster. En aparté, l'objet 'this' est-il disponible pour le gestionnaire appelé si je ne le passe pas explicitement? C'est à dire. est-ce que ça a une portée mondiale? – kdtop

+0

merci, cela fonctionne très bien! – kdtop

+1

L'appelant (le navigateur) définit 'this' à l'élément sur lequel l'événement a été enregistré lors de l'appel de votre gestionnaire. Un peu comme: 'myDiv.handler.call (myDiv, événement)' –