2010-06-17 5 views
0

Prenons l'exemple suivant:Dom Element onclick (MooTools :: éventuellement)

function async_callback(array1, array2, array3) { 
    // All arrays are equal length 

    for(var i = 0; i < array1.length; i++) { 
    var myElement = new Element('div', { 'id': 'dvMy' + i, 'events': { 'click': function() { SomeFunction(array1[i], array2[i], array3[i] } }}); 
    $(document).appendChild(myElement); 
    } 
} 

Maintenant, quand je clique sur mon élément, je reçois une valeur nulle pour les trois arguments. J'ai même essayé de faire: myElement.onclick = SomeFunction; // mais cela n'autorisera pas les arguments Je sais que je peux créer une chaîne et utiliser eval() et cela fonctionne, mais je n'aime pas eval().

Des idées ???

btw: Ceci est un exemple simple pour répliquer le problème, et pas le code réel.

Répondre

2

Ceci est votre gestionnaire:

function() { SomeFunction(array1[i], array2[i], array3[i] } } 

Au moment de son exécution, la boucle sera terminée et i sera donc égal au length du tableau, conformément à l'instruction conditionnelle (i < array1.length) et à l'instruction d'itération (i++).

La meilleure façon de résoudre c'est d'envelopper le gestionnaire dans une fonction immédiatement exécutée supplémentaire et passer i à lui, - cela aura pour effet de retenir la valeur de i dans une nouvelle fermeture:

for(var i = 0; i < array1.length; i++) { 
    var myElement = new Element('div', { 'id': 'dvMy' + i, 'events': { 
     'click': (function(i){ 
      return function() { SomeFunction(array1[i], array2[i], array3[i] } }; 
     }(i)) 
    }); 
    $(document).appendChild(myElement); 
} 
1

Ceci est un classique: lorsque le gestionnaire click s'exécute, i est défini sur la dernière valeur atteinte dans la boucle, qui est dans ce cas array1.length. Pour obtenir ce que vous voulez, vous devez appeler une fonction pour créer le gestionnaire de clic et passer la valeur de i:

function async_callback(array1, array2, array3) { 
    function createClickHandler(n) { 
    return function() { 
     SomeFunction(array1[n], array2[n], array3[n]); 
    }; 
    } 

    // All arrays are equal length 
    for(var i = 0; i < array1.length; i++) { 
    var myElement = new Element('div', { 
     'id': 'dvMy' + i, 
     'events': { 
     'click': createClickHandler(i) 
     } 
    }); 
    $(document).appendChild(myElement); 
    } 
}