Réponse courte
Utilisez ce CSS :
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
Plus soit ce JS (sans jQuery)...
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
Ou ce JS avec jQuery...
$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass('notransition'); // Re-enable transitions
... ou un code équivalent utilisant une autre bibliothèque ou un autre framework avec lequel vous travaillez.
Explication
Il s'agit en fait d'un problème assez subtil.
Tout d'abord, vous souhaitez probablement créer une classe "notransition" que vous pouvez appliquer aux éléments pour définir leur *-transition
Attributs CSS pour none
. Par exemple :
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
<i>(Petite parenthèse - notez l'absence d'un <code>-ms-transition</code> là-dedans. Vous n'en avez pas besoin. La première version d'Internet Explorer à prendre en charge les transitions <em>du tout </em>était IE 10, qui les supportait sans fixation).</i>
Mais ce n'est que du style, et c'est le plus facile. Lorsque vous essayerez d'utiliser cette classe, vous vous heurterez à un piège. Le piège est que le code comme celui-ci ne fonctionnera pas de la façon dont vous pourriez naïvement vous y attendre :
// Don't do things this way! It doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
someElement.classList.remove('notransition')
Naïvement, vous pourriez penser que le changement de hauteur ne sera pas animé, car il se produit lorsque la classe "notransition" est appliquée. En réalité, il sera être animé, du moins dans tous les navigateurs modernes que j'ai essayés. Le problème est que le navigateur met en cache les modifications de style qu'il doit effectuer jusqu'à ce que le JavaScript ait fini de s'exécuter, puis effectue toutes les modifications en une seule fois. En conséquence, il effectue une refonte où il n'y a pas de changement net de l'activation ou non des transitions, mais où il y a un changement net de la hauteur. Par conséquent, il anime le changement de hauteur.
Vous pourriez penser qu'une façon raisonnable et propre de contourner ce problème serait d'envelopper la suppression de la classe 'notransition' dans un délai d'attente de 1ms, comme ceci :
// Don't do things this way! It STILL doesn't work!
someElement.classList.add('notransition')
someElement.style.height = '50px' // just an example; could be any CSS change
setTimeout(function () {someElement.classList.remove('notransition')}, 1);
mais cela ne fonctionne pas non plus de manière fiable. Je n'ai pas réussi à faire en sorte que le code ci-dessus ne fonctionne pas dans les navigateurs WebKit, mais sur Firefox (sur des machines lentes et rapides) vous obtiendrez parfois (apparemment au hasard) le même comportement qu'en utilisant l'approche naïve. Je suppose que la raison en est qu'il est possible que l'exécution du JavaScript soit suffisamment lente pour que la fonction de délai d'attente soit en attente d'exécution au moment où le navigateur est inactif et qu'il penserait autrement à effectuer un reflux opportuniste, et si ce scénario se produit, Firefox exécute la fonction en attente avant le reflux.
La seule solution que j'ai trouvée à ce problème est de force une refonte de l'élément, en vidant les modifications CSS qui lui ont été apportées, avant de supprimer la classe "notransition". Il existe plusieurs façons de procéder - voir aquí pour certains. La méthode la plus proche d'une méthode "standard" consiste à lire le manuel de l'utilisateur. offsetHeight
de l'élément.
Une solution qui fonctionne réellement, alors, est
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
Voici un bidule JS qui illustre les trois approches possibles que j'ai décrites ici (à la fois l'approche réussie et les deux autres qui ont échoué) : http://jsfiddle.net/2uVAA/131/
1 votes
Cela semble prometteur : ricostacruz.com/jquery.transit . Il est sous licence MIT, vous pouvez donc soit l'intégrer, soit l'étudier pour voir comment il s'y prend.
0 votes
Toutes les réponses ajouter a
.notransition
classe. Il serait plus raisonnable de le faire dans l'autre sens, c'est-à-dire de cibler#elem.yestransition
avec votre css et supprimez cette classe. Cela permet de ne plus avoir de*
dans votre css.