muy simple ejemplo de JavaScript / jQuery: order de evaluación inesperada de instrucciones

Me sorprende el hecho de que una regla de transición CSS3 aplicada a través de jQuery después de un cambio de propiedad de CSS basado en jQuery en realidad anime este cambio de propiedad. Por favor, eche un vistazo a http://jsfiddle.net/zwatf/3/ :

Inicialmente, un div es diseñado por dos classs y tiene una cierta altura (200px) debido a las properties CSS pnetworkingeterminadas de estas dos classs. La altura se modifica con jQuery mediante la eliminación de una class:

$('.container').removeClass('active'); 

Esto networkinguce la altura de 200px a 15px.

Después de eso, se aplica una regla de transición al contenedor mediante la adición de una class:

 $('.container').addClass('all-transition'); 

Lo que está sucediendo es que la networkingucción de la altura se anima (en Firefox y Chrome, al less). En mi mundo, esto no debería suceder si el order de las instrucciones tiene algún significado.

Supongo que este comportamiento puede explicarse muy bien. ¿Por qué está sucediendo eso? ¿Cómo puedo prevenirlo?

Esto es lo que quiero lograr:

  1. modifique el estilo pnetworkingeterminado con jQuery (¡no animado por la transición CSS3!)
  2. aplicar la regla de transición con jQuery
  3. cambiar una propiedad con jQuery (animado por la transición CSS3)

(1) y (2) deben suceder lo más rápido posible, por lo que no me gusta trabajar con retrasos arbitrarios.

Cuando se ejecuta un script, el browser generalmente diferirá los cambios DOM al final para evitar el dibujo innecesario. Puede forzar un reflujo leyendo / escribiendo ciertas properties:

 var container = $('.container').removeClass('active'); var foo = container[0].offsetWidth; //offsetWidth makes the browser recalculate container.addClass('all-transition'); 

jsFiddle

O puede usar setTimeout con una duración corta, que básicamente hace lo mismo al dejar que el browser setTimeout a setTimeout automáticamente y luego agregar la class.

¿Por qué está sucediendo eso?

Supongo porque el DOM los ve aplicados juntos; acciones consecutivas inmediatas generalmente se almacenan en caching en lugar de aplicarse una después de la otra.

¿Cómo puedo prevenirlo?

Un time de espera (muy pequeño) debería hacerlo: http://jsfiddle.net/zwatf/4/

(a partir de los comentarios) La activación manual de un reflujo también ayuda: http://jsfiddle.net/zwatf/9/

No me gusta trabajar con retrasos arbitrarios.

Entonces, creo que la única otra forma posible es eliminar la height de las properties de css animadas, es decir, debe indicar explícitamente cuáles desea animar: http://jsfiddle.net/zwatf/5/

Creo que sucede demasiado rápido. Si haces esto:

 $('.container').toggleClass('active',function() { $('.container').addClass('all-transition'); }); 

se comportará como esperabas, ¿verdad?

Bien, bien, lo probé, pero no me di count de que no funcionó como se esperaba. Aquí una alternativa para reponerlo:

 $('.container').removeClass('active').promise().done(function(){ $('.container').addClass('all-transition'); $('.container').css('height','300'); //to see the easing });