2010-12-03 10 views
4

Désolé, mais apparemment je ne comprends pas assez enchaînant pour comprendre ce problème ...jQuery semble être en cours d'exécution simultanément plusieurs appels

Je mettre en place un plugin jQuery carrousel (jCarouselLite) et je suis en train d'ajouter une option « supprimer » l'un des éléments du carrousel (actuellement <div class="remove">) ...

initEvents: function() { 
     var self = this; 
     // Bind jQuery event for REMOVE button click 
     $('.remove').live('click', function() {  
      // Need to save the ID that we're removing 
      var item = $(this).closest('li.sort'); 
      var itemId = item.attr("id"); 

      $(this).removeItem(); 

      self.refreshDisplay(itemId); 
     }); 


$.fn.removeItem = (function() { 
    var item = this.closest('li.sort'); // could save this call by passing param 

    item.fadeOut("normal", function() { 
     $(this).remove(); 
     }); 

    // preserve jQuery chain 
    return this; 
}); 
}, 

refreshDisplay(itemId) { 
    // ... 
    // redraws carousel 
    // ... 
    // itemId is used to remove from the array of Items to show (class-wide scope) 
} 

Comme il n'y a aucun moyen propre à « rafraîchir » le plugin jCarouselLite (peut-être quelque chose que je vais essayer de mettre en œuvre dans le réel plugin plus tard) la solution rapide et sale pour cela est de simplement régénérer le carrousel.

Le problème est que j'essaie de faire disparaître l'élément cliqué, cependant, il semble que refreshDisplay() soit appelé avant que l'animation de fondu (et de suppression) de l'élément cliqué soit terminée. J'ai vérifié cela en commentant la ligne self.refreshDisplay(itemId); et il s'estompe et supprime comme prévu.

Donc je suppose qu'il y a une certaine façon dont j'ai besoin d'enchaîner ceci? J'ai fait quelques heures de lecture sur comment fonctionne le chaînage et j'ai cru comprendre, mais apparemment pas.

Toute aide est appréciée, merci!

Répondre

3

Le but du chaînage est de permettre à plusieurs commandes de partager un objet de base, mais cela n'empêche pas chaque commande d'attendre la commande précédente.

Pour cela, vous devez utiliser un rappel. Quelque chose comme

initEvents: function() { 
     var self = this; 
     // Bind jQuery event for REMOVE button click 
     $('.remove').live('click', function() {  
      // Need to save the ID that we're removing 
      var item = $(this).closest('li.sort'); 
      var itemId = item.attr("id"); 

      $(this).removeItem(function() { 
       self.refreshDisplay(itemId); 
      }); 
     }); 


$.fn.removeItem = (function(callback) { 
    var item = this.closest('li.sort'); // could save this call by passing param 

    item.fadeOut("normal", function() { 
     $(this).remove(); 
     callback(); //now your refresh is being called after the fade. 
     }); 

    // preserve jQuery chain 
    return this; 
}); 
}, 
+1

Battez-moi à lui! +1, Jacob est complètement correct ;-) A noter également - ce n'est pas "jQuery" qui appelle les choses simultanément, son javascript en général. Rappelez-vous que l'évanouissement est une animation et que l'animation est gérée, je crois, en utilisant des délais d'attente (en attendant un peu de temps, puis en continuant avec l'animation). Pendant que les délais d'expiration sont en cours, votre moteur javascript continuera à exécuter toutes les commandes supplémentaires que vous avez écrites. L'équipe jQuery en est consciente et c'est pourquoi la plupart de ses fonctions d'animation prennent des fonctions de rappel optionnelles. – Pandincus

+0

Ah ok je pense que je vous comprends maintenant, je ne savais pas trop où mettre la méthode de rappel. Rétrospectivement, cela semble assez évident maintenant, doh! Merci beaucoup :) – Muers