2010-05-07 28 views
0

Le code Javascript jQuery suivant est inclus sur une page autrement vide..click() callback référence la variable locale de la méthode appelante au lieu de la copier par valeur

var element; 
$(function() { 
    for (var i = 0; i < 10; i++) { 
    element = $('<div>' + i + '</div>'); 
    element.click(function() { 
     alert(i); 
    }); 
    $('body').append(element); 
    } 
}); 

Le comportement souhaité est que ce code devrait générer 10 éléments div numérotés de 0 à 9. Lorsque vous cliquez sur un élément div, un message d'alerte affiche le numéro de l'élément div que vous avez cliqué sur (si un utilisateur clique sur l'élément div étiqueté '4', le popup d'alerte devrait montrer le numéro 4).

La fenêtre d'alerte affiche à la place le chiffre 10, quel que soit l'élément div cliqué.

Comment puis-je modifier ce code pour qu'il se comporte de la manière souhaitée?

+0

Le résultat est 10 et toujours 10 parce que 'I' est un var unique qui est itéré dans votre boucle for. Il finit à 10 à la fin de la boucle à cause de 'i ++'. Est-ce que votre question est plus sur l'extraction d'un nombre utile d'un div cliqué, ou pourquoi «je» se comporte de cette façon lors de la transmission d'une fonction à un gestionnaire d'événements? – artlung

Répondre

2

Vous devez transmettre la variable en tant que paramètre de fonction.

Par exemple:

function buildElement(i) { 
    var element = $('<div>' + i + '</div>'); 
    element.click(function() { 
     alert(i); 
    }); 
    $('body').append(element); 
} 

$(function() { 
    for (var i = 0; i < 10; i++) { 
     buildElement(i); 
    } 
}); 

Vous pouvez aussi le faire avec une fonction anonyme en ligne, comme ceci:

$(function() { 
    for (var i = 0; i < 10; i++) { 
     (function(i) { 
      var element = $('<div>' + i + '</div>'); 
      element.click(function() { 
       alert(i); 
      }); 
      $('body').append(element); 
     })(i); 
    } 
}); 
+0

+1 Pour bien utiliser les fermetures et le piratage comme les autres réponses. Mais cela devrait être 'var element = ...' –

+0

@Justin: Correction. – SLaks

0

Habituellement je cacher le numéro dans un id et le faire dans certains structuré chemin:

$(function() { 
    for (var i = 0; i < 10; i++) { 
     element = $('<div id="id-'+i+'">' + i + '</div>'); 
     element.click(function() { 
      alert($(this).attr('id').split('-')[1]); 
     }); 
     $('body').append(element); 
    } 
}); 
+0

Le vrai problème ici n'est pas l'utilisation d'une fermeture. Voir la réponse de SLaks. –

0

Vous pouvez faire 1 de deux choses. Vous pouvez utiliser le contenu de la div pour afficher ou vous pouvez saisir l'index dans le tableau à partir d'un sélecteur.

Voici un exemple du contenu:

element.click(function() { 
    alert($(this).text()); 
}); 

Ou pour l'indice:

element.click(function() { 
    alert($('div').index(this)); 
}); 

Je crois que les deux devraient travailler

+0

Bien que cela semble fonctionner, cela ignore le problème réel et simple de l'utilisation correcte des fermetures. –

+0

La question n'était pas de savoir comment utiliser les fermetures. Je ne vois pas de problème avec l'offre d'une autre solution qui répond à la question posée. – MacAnthony

+0

Vous avez raison, la question n'était pas de savoir comment utiliser la fermeture, mais les fermetures sont la réponse appropriée et utilisent le langage tel qu'il est conçu. Inutilement accéder au DOM est juste cela: inutile. –