2013-09-01 2 views
-2

Je suis confronté à un comportement étrange avec la méthode .append() de jQuery..append() de jQuery: comportement étrange

var container = $('#container'); 


var buttons = { 
    'Okay': function() { 
     return 'Yeah, I\'m okay with this.'; 
    }, 
    'Nope': function() { 
     return 'No, no, definitively no.'; 
    }, 
    'Maybe': function() { 
     return 'Hum, maybe.'; 
    } 
}; 


for(var button_label in buttons) { 
    var button_callback = buttons[button_label]; 

    var button_html = $('<button type="button">' + button_label + '</button>'); 

    button_html.on('click', function() { 
     alert('button : ' + $(this).text() + ', callback : ' + button_callback()); 
    }); 

    container.append(button_html); 
} 

View the code on JS Bin

Tout fonctionne très bien, sauf, comme vous pouvez le voir, en cliquant sur les boutons: le même rappel est appelée (le dernier défini dans l'objet buttons). J'ai vérifié le document de jQuery, et c'est peut-être lié:

S'il y a plus d'un élément cible, les copies clonées de l'élément inséré seront créées pour chaque cible après la première.

Ou, j'ai besoin de refactoriser mon code. J'ai testé différentes solutions, mais aucune n'a fonctionné. Est-ce que quelqu'un peut m'aider ?

Répondre

5

C'est le bon vieux problème "variable dans une boucle passée à un rappel" qui existe ici sur Stack Overflow un milliard de fois. Donc ce n'est pas du tout lié à jQuery.

Ce que vous devez faire est de créer une nouvelle variable au cours de chaque boucle. La façon la plus simple de le faire est d'utiliser une fonction anonyme qui est exécutée immédiatement et reçoit la valeur en tant que paramètre.

(function(button_callback) { 
    button_html.on('click', function() { 
     alert('button : ' + $(this).text() + ', callback : ' + button_callback()); 
    }); 
})(button_callback); 

Updated JSBin

Pourquoi est-ce nécessaire? En JavaScript, il n'y a pas de portée de bloc. Seules les fonctions créent une nouvelle portée. Donc, dans votre code original, var button_callback est hissé en haut de la portée (la fonction contenant votre boucle ou la portée globale s'il n'y en a pas). Donc à chaque itération vous avez la même variable. Et cette variable est liée à la fermeture de votre fonction anonyme. Donc, après la boucle, la variable a la dernière valeur - dans les trois fonctions.

+0

Vous pouvez ajouter un bel article à propos de IIFE comme celui-ci: http://benalman.com/news/2010/11/immediately-invoked-function-expression/ –

+0

Merci voleur pour votre réponse détaillée (même si c'est une question noob , Je n'utilise pas JS tous les jours), et merci pour le mec qui m'a répondu en pensant que je suis un total sans vie, sachant que chaque communauté gouverne de bout en bout. – Epoc