2010-06-24 5 views
30

Je suis content ajout à une liste à l'aide:Jquery - Effectuer le rappel après append

$('a.ui-icon-cart').click(function(){ 
     $(this).closest('li').clone().appendTo('#cart ul'); 
    }); 

Je veux effectuer d'autres fonctions au contenu en annexe (classe du changement, appliquer des animations, etc.)

Comment puis-je effectuer un rappel sur cette fonction qui me permettra d'effectuer des fonctions sur les données ajoutées?

Répondre

26

.each() de jQuery prend une fonction de rappel et l'applique à chaque élément de l'objet jQuery.

Imaginez quelque chose comme ceci:

$('a.ui-icon-cart').click(function(){ 
    $(this).closest('li').clone().appendTo('#cart ul').each(function() { 
    $(this).find('h5').remove(); 
    $(this).find('img').css({'height':'40px', 'width':'40px'}); 
    $(this).find('li').css({'height':'60px', 'width':'40px'}); 
    }); 
}); 

Vous pouvez aussi simplement stocker le résultat et le travail sur elle à la place:

$('a.ui-icon-cart').click(function(){ 
    var $new = $(this).closest('li').clone().appendTo('#cart ul') 
    $new.find('h5').remove(); 
    $new.find('img').css({'height':'40px', 'width':'40px'}); 
    $new.find('li').css({'height':'60px', 'width':'40px'}); 
}); 

Je suggère également qu'au lieu de mofiying le CSS comme vous venez ajoutez une classe à votre li cloné comme ceci:

$(this).closest('li').clone().addClass("new-item").appendTo('#cart ul'); 

Ensuite, installez des styles comme:

.new-item img, .new-item li { height: 40px; width: 40px; } 
.new-item h5 { display: none } 
+0

Hmm .. le 2ème exemple serait encore déclenché de manière asynchrone et ne fonctionnerait pas dans la plupart des cas quand ils avaient besoin du callback * après * l'appendTo – Trip

+0

Je ne suis pas sûr de comprendre ce que signifie asynch @Trip --- Tout cela le code ci-dessus est synch. Il n'y a pas d'appels asynchrones dans ce code. Même le rappel à l'intérieur de chacun est toujours synchrone, il est appelé immédiatement. La seule différence dans l'un ou l'autre exemple est que le premier crée une nouvelle portée à l'intérieur de chacun que vous pouvez avoir pour stocker des variables pour chaque élément correspondant, sinon ils devraient fonctionner de manière identique. – gnarf

+1

J'avais tort! Merci :) – Trip

4

Vous pouvez continuer à enchaîner d'autres opérations au point-virgule.

$(this).closest('li').clone().appendTo('#cart ul').addClass('busy').fade('fast'); 

etc

+2

Comment puis-je mettre en œuvre cela en une chaîne. $ (this) .Find ('h5') enlever(); \t \t \t $ (this) .find ('img'). Css ('hauteur', '40px', 'largeur', '40px'); \t \t \t $ (this) .find ('li'). Css ('hauteur', '60px', 'largeur', '40px'); – user342391

+1

Cela n'aide pas, la question est comment vous pouvez appliquer un rappel après que l'opération d'ajout est effectuée. Les opérations DOM sont effectuées de manière asynchrone. Ainsi, dans la partie suivante de la chaîne, le contenu ajouté n'est pas encore visible. – douwe

16

Unfortunatly ajoutant callbacks aux opérations dom est pas quelque chose qui peut être fait de façon soignée en utilisant javascript. Pour cette raison, il ne figure pas dans la bibliothèque jQuery. Un settimeout avec la minuterie "1 ms" met toujours la fonction dans le settimeout au bas de la pile d'appels. Cela fonctionne! La bibliothèque underscore.js utilise cette technique dans _.defer, qui fait exactement ce que vous voulez.

$('a.ui-icon-cart').click(function(){ 
    $(this).closest('li').clone().appendTo('#cart ul'); 
    setTimeout(function() { 
     // The LI is now appended to #cart UL and you can mess around with it. 
    }, 1); 
}); 
+2

DOM Les opérations sont synchronisées, il n'y a aucune raison de '_.defer' quoi que ce soit – gnarf

+0

Merci, c'est exactement ce dont j'avais besoin! Mon cas était d'ajouter l'entité html à un conteneur, plutôt que de lui lier un événement. Été luttant pour le faire fonctionner pendant un moment ... –

+0

Awesome! Pas la solution la plus évidente que j'ai rencontrée, mais ça marche :-) – bestprogrammerintheworld