2012-08-23 17 views
33

No encuentro una forma de usar transiciones css en elementos dom recién creados.transiciones css en elementos nuevos

digamos que tengo un documento html vacío.

<body> 
    <p><a href="#" onclick="return f();">click</a></p> 
</body> 

También tengo este css

#id { 
    -moz-transition-property: opacity; 
    -moz-transition-duration: 5s; 
    opacity: 0; 
} 

#id.class { 
    opacity: 1; 
} 

y esto js

function f() { 
    var a = document.createElement('a'); 
    a.id = 'id'; 
    a.text = ' fading in?'; 
    document.getElementsByTagName('p')[0].appendChild(a); 
    // at this point I expect the span element to be with opacity=0 

    a.className = 'class'; 
    // now I expect the css transition to go and "fade in" the a   

    return false; 
} 

pero, como se puede ver en http://jsfiddle.net/gwxkW/1/ al hacer clic en el elemento aparece instantáneamente.

Si trato de establecer la clase en un timeout() i menudo encuentro el resultado, pero me parece más una carrera entre javascript y css el motor. ¿Hay algún evento específico para escuchar? Traté de usar document.body.addEventListener('DOMNodeInserted', ...) pero no está funcionando.

¿Cómo puedo aplicar transiciones CSS a los elementos recién creados?

+0

Configurar el nombre de clase con un trabajo 'setTimeout', pero solo si la demora es de 6ms o más para mí. No estoy seguro de una buena manera. – pimvdb

+0

sí, probé un valor de milisegundos bajo (rango 0-10) y la mayoría de las veces funciona con 5-6 ms, pero * siento * que es el enfoque equivocado. Lo que esperaba es algún tipo de evento relacionado con "a partir de este momento se aplican las CSS", pero no sé si existen –

+0

Ver http: // stackoverflow.com/questions/18564942/clean-way-to-programmatically-use-css-transitions-from-js para la discusión de una manera limpia de hacer esto. – Nickolay

Respuesta

37

En Firefox, parece ser una carrera entre la finalización del diseño y la transición de CSS. Chrome es mucho más predecible. Si configuro el nombre de clase en setTimeout(), Chrome siempre funciona, Firefox solo funciona si el tiempo setTimeout() es largo.

Con este código en Firefox (incluso utilizando la setTimeout()), el texto muestra inmediatamente:

function f() { 
    var a = document.createElement('a'); 
    a.id = 'id'; 
    a.innerHTML = ' fading in?'; 
    document.getElementsByTagName('p')[0].appendChild(a); 
    // at this point I expect the span element to be with opacity=0 

    setTimeout(function() { 
     a.className = 'fadeIn'; 
    }, 10); 
    return false; 
} 

Pero, si fuerzo un reflujo mediante la solicitud de una propiedad que sólo puede ser devuelto después de la disposición, que luego empieza para trabajar en Firefox:

function f() { 
    var a = document.createElement('a'); 
    a.id = 'id'; 
    a.innerHTML = ' fading in?'; 
    document.getElementsByTagName('p')[0].appendChild(a); 
    // at this point I expect the span element to be with opacity=0 

    // request property that requires layout to force a layout 
    var x = a.clientHeight; 
    setTimeout(function() { 
     a.className = 'fadeIn'; 
    }, 10); 
    return false; 
} 

por otra parte, una vez que he pedido esa propiedad para forzar un diseño, incluso puedo quitar el setTimeout() y la animación funciona en Firefox.

function f() { 
    var a = document.createElement('a'); 
    a.id = 'id'; 
    a.innerHTML = ' fading in?'; 
    document.getElementsByTagName('p')[0].appendChild(a); 
    // at this point I expect the span element to be with opacity=0 

    // request property that requires layout to force a layout 
    var x = a.clientHeight; 
    a.className = 'fadeIn'; 
    return false; 
} 

Se puede ver este último trabajo aquí, tanto en Chrome y Firefox: http://jsfiddle.net/jfriend00/phTdt/

Y, aquí está un artículo que analiza el fenómeno: http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html

+0

gracias por el enlace: aunque encontré esta solución un poco * hackish * al menos está claramente motivada –

+0

Sin embargo, el truco de propiedad no funciona para múltiples artículos; solo el retraso lo hace. –

12

he encontrado una manera más agradable para desencadenar la disposición y hacen transiciones funcionan justo después añadiendo el elemento a la DOM:

window.getComputedStyle(element).opacity; 
+1

Esa solución también se discute en la parte inferior de este artículo por Tim Taubert: https://timtaubert.de/blog/2012/09/css-transitions-for-dynamically-created-dom-elements/ – robocat

+1

No utilizaría '.cssText', ya que es bastante pesado (serializa todos los estilos). – Nickolay

+0

simplemente use '.opacity' en su lugar, esto debe usarse de todos modos, porque este es el estilo que debe ser terminado por el motor de renderizado – timaschew

Cuestiones relacionadas