2010-10-19 25 views
18

J'essaye de d'animer un élément html créé dynamiquement avec transitions CSS3.Transitions CSS3 aux éléments créés dynamiquement

Je souhaite que l'animation commence juste avant la création de l'élément.
Pour ces i créer une classe qui a mis la position initiale de l'élément et puis je régler la position cible par le jquery css() méthode

Mais le nouvel élément, il apears juste dans la position cible sans transition .

Si j'utilise setTimeout de 0ms pour définir la nouvelle valeur css, cela fonctionne.

Il y a quelque chose que je fais mal? ou est une limitation? Je ne pense pas que je devrais avoir besoin d'utiliser la solution de contournement setTimeout.

Merci!

MISE À JOUR: Voici un lien avec le code qui s'exécute sur jsfiddle.net pour que vous puissiez expérimenter. http://jsfiddle.net/blackjid/s9zSH/

MISE À JOUR J'ai mis à jour l'exemple avec la solution dans la réponse.
http://jsfiddle.net/s9zSH/52/

Voici un code exemple entièrement

<html> 
    <head> 
     <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script> 
     <script type="text/javascript"> 

     //Bind click event to the button to duplicate the element 
     $(".duplicate").live("click", function (e){ 
      var $to = $("#original .square").clone() 
      $("body").append($to); 
      if($(e.target).hasClass("timeout")) 
       //With setTimeout it work 
       setTimeout(function() { 
        $to.css("left", 200 + "px"); 
       },0); 
      else if($(e.target).hasClass("notimeout")) 
       // These way it doesn't work 
       $to.css("left", 200 + "px"); 
     }); 

     </script> 
     <style type="text/css"> 
     .animate{ 
      -webkit-transition: all 1s ease-in; 
     } 
     .square{ 
      width:50px; 
      height:50px; 
      background:red; 
      position:relative; 
      left:5px; 
     } 
     </style> 
    </head> 
    <body> 
     <div id="original"> 
      <div class="square animate"></div> 
     </div> 

     <button class="duplicate timeout">duplicate with setTimeout</button> 
     <button class="duplicate notimeout">duplicate without setTimeout</button> 
    </body> 
</html> 

Répondre

17

Vous n'avez pas besoin d'utiliser un délai d'attente. Le délai d'expiration fonctionne car la page est redistribuée entre les styles de paramètre. Reflowing recalcule les styles. Si vous ne recalculez pas les styles, le second style écrase simplement le premier. C'est le vrai problème.

Au contraire, vous pouvez simplement:

obj.className = style1; 
window.getComputedStyle(obj).getPropertyValue("top"); 
obj.className = style2; 

Si vous animez plusieurs objets, il vous suffit de "pompe" la calculatrice de style une fois:

obj.className = style1; 
obj2.className = style1; 
obj3.className = style1; 
window.getComputedStyle(obj).getPropertyValue("top"); 

obj.className = style2; 
obj2.className = style2; 
obj3.className = style2; 

Testé chrome12 sur mac

+1

addendum: bien que vous n'ayez pas à utiliser le timeout, parfois cela peut être bon. Cela dépend vraiment de votre application. forcer le recalcul synchrone des styles, si c'est fait fréquemment, peut faire que votre UI bégaie. Si cela se produit, utilisez timeout judicieusement pour décomposer/amortir une animation complexe sur quelques images. – mmaclaurin

+0

Merci, c'est la première explication que j'ai trouvée de * pourquoi * un setTimeout est efficace pour forcer les transitions CSS. –

+0

Wow, super! Tu as sauvé ma journée. J'ai perdu pas mal de temps pour trouver la raison, finalement tu l'as résolu. Merci encore! –