2010-10-19 10 views
18

Sto provando a animare un elemento html creato dinamicamente con transizioni CSS3.Transizioni CSS3 agli elementi creati dinamicamente

Desidero che l'animazione venga avviata appena prima della creazione dell'elemento.
Per questi Creo una classe che impostare la posizione iniziale dell'elemento e poi impostare la posizione di destinazione dal jquery css() metodo

Ma il nuovo elemento appena apears nella posizione di destinazione senza transizione .

Se utilizzo un setTimeout di 0 ms per impostare il nuovo valore css funziona.

C'è qualcosa che sto sbagliando? o è una limitazione? Non penso che avrei bisogno di usare la soluzione alternativa a setTimeout.

Grazie!

UPDATE: questo è un collegamento con il codice in esecuzione su jsfiddle.net per il tuo esperimento. http://jsfiddle.net/blackjid/s9zSH/

UPDATE Ho aggiornato l'esempio con la soluzione nella risposta.
http://jsfiddle.net/s9zSH/52/

Ecco un esempio di codice completamente funzionante

<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> 

risposta

17

Non è necessario utilizzare un timeout. Timeout funziona perché la pagina viene riportata tra gli stili di impostazione. Il reflowing ricalcola gli stili. Se non ricalcoli gli stili, il secondo stile sovrascrive semplicemente il primo. Questo è il vero problema.

Piuttosto, si può semplicemente:

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

Se state animando più oggetti, è solo bisogno di "pompa" il calcolatore di stile una volta:

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

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

Testato in chrome12 su Mac

+1

addendum: mentre non è necessario utilizzare il timeout, a volte può essere buono. dipende davvero dalla tua applicazione. forzare il ricalcolo sincrono degli stili, se fatto di frequente, può far balbettare l'interfaccia utente. se lo trovi, usa il timeout in modo giudizioso per suddividere/ammortizzare un'animazione complessa su alcuni fotogrammi. – mmaclaurin

+0

Grazie, questa è la prima spiegazione che ho trovato su * perché * un setTimeout è efficace per forzare le transizioni CSS. –

+0

Wow, fantastico! Mi hai salvato la giornata. Ho perso parecchio tempo per scoprirne il motivo, finalmente l'hai risolto. grazie ancora! –