javascript - transiciones - ¿Cuál es la forma más limpia de desactivar temporalmente los efectos de transición CSS?
transiciones css ejemplos (8)
Respuesta corta
Use este CSS:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
Además de este JS (con jQuery) ...
$someElement.addClass(''notransition''); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass(''notransition''); // Re-enable transitions
... o JavaScript equivalente utilizando funciones DOM sin procesar o cualquier otro marco con el que estés trabajando.
Explicación
Este es en realidad un problema bastante sutil.
En primer lugar, es probable que desee crear una clase ''notransition'' que pueda aplicar a los elementos para establecer sus atributos CSS *-transition
en none
. Por ejemplo:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
(Dejando de lado un -ms-transition
un lado: tenga en cuenta la falta de una -ms-transition
allí. No la necesita. La primera versión de Internet Explorer que admite transiciones fue IE 10, que las admitió sin prearranque).
Pero eso es solo estilo, y es lo más fácil. Cuando vengas a probar y usar esta clase, te encontrarás con una trampa. La trampa es que un código como este no funcionará de la manera que podrías esperar ingenuamente:
// Don''t do things this way! It doesn''t work!
$someElement.addClass(''notransition'')
$someElement.css(''height'', ''50px'') // just an example; could be any CSS change
$someElement.removeClass(''notransition'')
Ingenuamente, podrías pensar que el cambio de altura no será animado, porque ocurre mientras se aplica la clase ''no transmisión''. En realidad, sin embargo, estará animado, al menos en todos los navegadores modernos que he probado. El problema es que el navegador almacena en caché los cambios de estilo que debe realizar hasta que el JavaScript haya terminado de ejecutarse, y luego realiza todos los cambios en un solo reflujo. Como resultado, realiza un reflujo donde no hay un cambio neto en si las transiciones están habilitadas o no, pero hay un cambio neto en la altura. En consecuencia, anima el cambio de altura.
Podría pensar que una forma razonable y limpia de evitar esto sería eliminar la eliminación de la clase ''notransition'' en un tiempo de espera de 1 ms, como este:
// Don''t do things this way! It STILL doesn''t work!
$someElement.addClass(''notransition'')
$someElement.css(''height'', ''50px'') // just an example; could be any CSS change
setTimeout(function () {$someElement.removeClass(''notransition'')}, 1);
pero esto tampoco funciona de manera confiable tampoco. No pude hacer que el código anterior se rompa en los navegadores WebKit, pero en Firefox (tanto en máquinas lentas como rápidas) a veces (aparentemente al azar) obtienes el mismo comportamiento que con el enfoque ingenuo. Supongo que la razón es que la ejecución de JavaScript es lo suficientemente lenta para que la función de tiempo de espera esté lista para ejecutarse cuando el navegador está inactivo y estaría pensando en hacer un reflujo oportunista, y si ese escenario sucede, Firefox ejecuta la función en cola antes del reflujo.
La única solución que he encontrado para el problema es forzar un reflujo del elemento, eliminando los cambios de CSS realizados en él, antes de eliminar la clase ''notransition''. Hay varias formas de hacer esto: mira here para algunos. Lo más parecido a una forma "estándar" de hacer esto es leer la propiedad offsetHeight
del elemento.
Una solución que realmente funciona, entonces, es
$someElement.addClass(''notransition''); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass(''notransition''); // Re-enable transitions
Aquí hay un violín de JS que ilustra los tres enfoques posibles que he descrito aquí (tanto el enfoque exitoso como los dos fallidos): http://jsfiddle.net/2uVAA/35/
Tengo un elemento DOM con algunos / todos los siguientes efectos aplicados:
#elem {
-webkit-transition: height 0.4s ease;
-moz-transition: height 0.4s ease;
-o-transition: height 0.4s ease;
transition: height 0.4s ease;
}
Estoy escribiendo un complemento de jQuery que está redimensionando este elemento. Necesito desactivar estos efectos temporalmente para poder cambiar el tamaño sin problemas.
¿Cuál es la forma más elegante de desactivar estos efectos temporalmente (y luego volver a habilitarlos), dado que pueden ser aplicados por los padres o no aplicarse en absoluto?
Agregue una clase CSS adicional que bloquee la transición y luego elimínela para volver al estado anterior. Esto hace que el código CSS y JQuery sea breve, simple y bien comprensible.
CSS :
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
-ms-transition: none !important;
transition: none !important;
}
!important
se agregó para asegurarse de que esta regla tendrá más "peso", porque el ID es normalmente más específico que la clase.
JQuery :
$(''#elem'').addClass(''notransition''); // to remove transition
$(''#elem'').removeClass(''notransition''); // to return to previouse transition
Creo que podrías crear una clase de CSS separada que puedas usar en estos casos:
.disable-transition {
-webkit-transition: none;
-moz-transition: none;
-o-transition: color 0 ease-in;
-ms-transition: none;
transition: none;
}
Luego, en jQuery, deberías alternar la clase así:
$(''#<your-element>'').addClass(''disable-transition'');
Para una solución JS pura (sin clases CSS), simplemente configure la transition
a ''none''
. Para restaurar la transición como se especifica en el CSS, establezca la transition
a una cadena vacía.
// Remove the transition
elem.style.transition = ''none'';
// Restore the transition
elem.style.transition = '''';
Si usa prefijos de proveedor, deberá configurarlos también.
elem.style.webkitTransition = ''none''
Puede deshabilitar animación, transición, trasformaciones para todo el elemento en la página con este código CSS
var style = document.createElement(''style'');
style.type = ''text/css'';
style.innerHTML = ''* {'' +
''/*CSS transitions*/'' +
'' -o-transition-property: none !important;'' +
'' -moz-transition-property: none !important;'' +
'' -ms-transition-property: none !important;'' +
'' -webkit-transition-property: none !important;'' +
'' transition-property: none !important;'' +
''/*CSS transforms*/'' +
'' -o-transform: none !important;'' +
'' -moz-transform: none !important;'' +
'' -ms-transform: none !important;'' +
'' -webkit-transform: none !important;'' +
'' transform: none !important;'' +
'' /*CSS animations*/'' +
'' -webkit-animation: none !important;'' +
'' -moz-animation: none !important;'' +
'' -o-animation: none !important;'' +
'' -ms-animation: none !important;'' +
'' animation: none !important;}'';
document.getElementsByTagName(''head'')[0].appendChild(style);
Recomendaría deshabilitar la animación según lo sugerido por DaneSoul, pero haciendo que el cambio sea global:
/*kill the transitions on any descendant elements of .notransition*/
.notransition * {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
-ms-transition: none !important;
transition: none !important;
}
.notransition
se puede aplicar al elemento del body
, anulando de forma efectiva cualquier animación de transición en la página:
$(''body'').toggleClass(''notransition'');
Tendría una clase en tu CSS así:
.no-transition {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
-ms-transition: none;
transition: none;
}
y luego en tu jQuery:
$(''#elem'').addClass(''no-transition''); //will disable it
$(''#elem'').removeClass(''no-transition''); //will enable it
hace
$(''#elem'').css(''-webkit-transition'',''none !important'');
en tu js matarlo?
obviamente repetir para cada uno.