2010-08-25 3 views
0

J'utilise un prototype pour attacher des gestionnaires d'événements à un certain nombre de champs de formulaire. Les champs de formulaire sont nommés "ContactAddress", "ContactCity", "ContactState", "ContactZip" ainsi qu'un autre jeu commençant par "ContactProfile". Maintenant, l'événement doit être en mesure de faire la différence entre le moment où je mettre à jour un champ « Contact » et un champ « ContactProfile » J'ai donc une structure de données et le code qui fonctionne comme ceci:Javascript/Prototype ajoutant deux gestionnaires d'événements à un seul champ quand j'en veux un

var geos = { 
    'Contact' : [ 
     'Address', 'City', 'State', 'Zip' 
    ], 
    'ContactProfile' : [ 
     'Address', 'City', 'State', 'Zip' 
    ] 
}; 
// Called on page load 
function watchGeo() { 
    for(prefix in geos) { 
     geos[prefix].each(function(item) { 
      $(prefix + item).observe('change', function() {ajaxgeolocate(prefix, item);}); 
     }) 
    } 
} 
// Doesn't actually geolocate anything yet, just tells me that the event works and what params got passed. 
function ajaxgeolocate(prefix, suffix) { 
    alert(prefix + " " + suffix); 
} 

À En chargeant la page, quand je change l'un des champs ContactProfile, il me donne une boîte d'alerte qui dit "ContactProfile Address" (par exemple) comme il se doit. Cependant, si je change l'un des champs de contact, il me donne une boîte d'alerte qui indique également "ContactProfile Address". Curieux, j'ai inspecté le terrain et j'ai découvert que deux gestionnaires d'événements avaient été ajoutés à tous les champs Contact, au lieu d'un seul. Les champs ContactProfile ont tous un événement, comme ils le devraient.

Que se passe-t-il ici?

+0

Aucune offense, et j'apprécie la réponse finale, mais vous littéralement répondu à ma question dans une minute ou deux de mon affectation, et à première vue il ne me semble pas que vous aviez même compris la question en premier lieu. Après quelques autres coups de ma tête contre le mur, j'ai finalement déroulé la boucle et je n'ai pas vérifié pendant quelques jours, donc je n'ai pas vu ta réponse finale jusqu'à maintenant. Néanmoins, j'apprécie le fait que vous avez fait l'effort supplémentaire d'obtenir une réponse correcte, et pour cela vous obtiendrez une acceptation. :) – AlexMax

Répondre

1

Il arrive ici:

function watchGeo() { 
    for(prefix in geos) { 
     geos[prefix].each(function(item) { 
      //alert($(prefix + item)) 
      $(prefix + item).observe('change', function() {ajaxgeolocate(prefix, item);}); 
     }) 
    } 
} 

Le « préfixe » variable est un membre du « watchGeo » et est inclus dans la fonction de fermeture est passé à .Chaque(). Cependant, lorsque vous arrivez au 2ème préfixe, le premier est écrasé dans toutes les fermetures précédentes passées à .each(). En outre, c'est encore pire, 'préfixe' devient une variable globale puisque vous ne le déclarez jamais dans la portée de la fonction.

Essayez:

function appendGeoWatcher(prefix, item) { 
    $(prefix + item).observe('change', function() {ajaxgeolocate(prefix, item);}); 
} 

function watchGeo() { 
    for(var prefix in geos) { // var prefix, keeps it local. 
     geos[prefix].each(function(item) { 
      appendGeoWatcher(prefix, item) 
     }); 
    } 
} 
+0

Si tel était le cas, pourquoi n'y a-t-il pas deux gestionnaires d'événements dans chaque domaine? – AlexMax

+0

Mise à jour, était amusant de le trouver; oP – BGerrissen

+0

Ah, c'était assez perspicace. Je l'avais en fait «réparé» il y a un jour ou deux en déroulant la boucle et en faisant huit appels séparés, mais c'était perspicace. – AlexMax

Questions connexes