Las transiciones CSS no funcionan cuando se asignan a través de JavaScript


Estoy teniendo un gran dolor de cabeza tratando de aplicar transiciones CSS3 a una presentación de diapositivas a través de JavaScript.

Básicamente el JavaScript obtiene todas las diapositivas en la presentación y aplica clases CSS a los elementos correctos para dar un buen efecto animado, si no hay soporte para transiciones CSS3, solo aplicará los estilos sin una transición.

Ahora, mi "pequeño" problema. Todo funciona como se esperaba, todas las diapositivas obtienen los estilos correctos, el código se ejecuta sin errores (hasta ahora). Pero el las transiciones especificadas no funcionan, aunque se hayan aplicado los estilos correctos. Además, los estilos y transiciones funcionan cuando los aplico yo mismo a través del inspector.

Como no pude encontrar una explicación lógica yo mismo pensé que alguien aquí podría responderla, ¿por favor?

He reunido un pequeño ejemplo de lo que es el código en este momento: http://g2f.nl/38rvma O use JSfiddle (sin imágenes): http://jsfiddle.net/5RgGV/1 /

Author: ThinkingStiff, 2011-11-21

4 answers

Para hacer que transition funcione, tres cosas tienen que suceder.

  1. el elemento tiene que tener la propiedad explícitamente definida, en este caso: opacity: 0;
  2. el elemento debe tener la transición definida: transition: opacity 2s;
  3. la nueva propiedad debe ser establecida: opacity: 1

Si está asignando 1 y 2 dinámicamente, como en su ejemplo, debe haber un retraso antes de 3 para que el navegador pueda procesar la solicitud. La razón por la que funciona cuando lo está depurando es que está creando este retraso al pasar a través de él, dando tiempo al navegador para procesar. Dar un retraso a la asignación .target-fadein:

window.setTimeout( function() { slides[targetIndex].className += " target-fadein"; }, 100 ); 

O ponga .target-fadein-begin en su HTML directamente para que se analice al cargar y esté listo para la transición.

Agregar transition a un elemento no es lo que desencadena la animación, sino cambiar la propiedad.

Demo: http://jsfiddle.net/ThinkingStiff/QNnnQ /

HTML:

<div id="fade1" class="fadeable">fade 1 - works</div>
<div id="fade2">fade 2 - doesn't work</div>
<div id="fade3">fade 3 - works</div>

CSS:

.fadeable {
    opacity: 0;
}

.fade-in {
    opacity: 1;
    transition:             opacity 2s;
        -moz-transition:    opacity 2s;
        -ms-transition:     opacity 2s;
        -o-transition:      opacity 2s;
        -webkit-transition: opacity 2s;
}

Script:

//works
document.getElementById( 'fade1' ).className += ' fade-in';

//doesn't work
document.getElementById( 'fade2' ).className = 'fadeable';
document.getElementById( 'fade2' ).className += ' fade-in';

//works
document.getElementById( 'fade3' ).className = 'fadeable';
window.setTimeout( function() {

    document.getElementById( 'fade3' ).className += ' fade-in';

}, 100);
 44
Author: ThinkingStiff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-15 17:10:42

Aquí hay un ejemplo (JSFiddle) de una transición de fundido que funciona con un disparador Javascript.

 3
Author: Nate B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-21 14:26:25

Engañar al motor de diseño!

function finalizeAndCleanUp (event) {
    if (event.propertyName == 'opacity') {
        this.style.opacity = '0'
        this.removeEventListener('transitionend', finalizeAndCleanUp)
    }
}
element.style.transition = 'opacity 1s'
element.style.opacity = '0'
element.addEventListener('transitionend', finalizeAndCleanUp)
// next line's important but there's no need to store the value
element.offsetHeight
element.style.opacity = '1'

Como ya se mencionó, transitiontrabaja interpolando del estado A al estado B. Si su script hace cambios en la misma función, layout engine no puede separar donde termina el estado A y comienza B. A menos que le des una pista.

Dado que no hay oficial manera de hacer la indirecta, usted debe confiar en los efectos secundarios de algunas funciones. En este caso .offsetHeight getter que implícitamente hace que el motor de diseño detenga, evalúe y calcule todas las propiedades que se establecen y devuelva un valor. Por lo general, esto debe evitarse por implicaciones de rendimiento, pero en nuestro caso esto es exactamente lo que se necesita: consolidación del estado.

Código de limpieza añadido para completar.

 3
Author: transistor09,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-13 19:52:17

Algunas personas han preguntado por qué hay un retraso. El estándar quiere permitir que múltiples transiciones, conocidas como un evento de cambio de estilo, ocurran a la vez (como un elemento que se desvanece al mismo tiempo que gira a la vista). Desafortunadamente, no define una forma explícita de agrupar las transiciones que desea que ocurran al mismo tiempo. En su lugar, permite a los navegadores elegir arbitrariamente qué transiciones se producen al mismo tiempo por la distancia que se llaman. La mayoría de los navegadores parecen utilizar su frecuencia de actualización para definir este tiempo.

Aquí está el estándar si desea más detalles: http://dev.w3.org/csswg/css-transitions/#starting

 1
Author: user3723889,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-20 14:44:25