Kurze Antwort
Verwenden Sie dieses CSS:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
Plus entweder diese JS (ohne 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
Oder dieses JS mit jQuery ...
$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass('notransition'); // Re-enable transitions
... oder gleichwertiger Code mit einer anderen Bibliothek oder einem anderen Framework, mit dem Sie arbeiten.
Erläuterung
Dies ist eigentlich ein ziemlich subtiles Problem.
Zunächst möchten Sie wahrscheinlich eine 'notransition'-Klasse erstellen, die Sie auf Elemente anwenden können, um deren *-transition
CSS-Attribute festzulegen none
. Zum Beispiel:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
(Nebenbei bemerkt - beachten Sie das Fehlen eines -ms-transition
In. Sie benötigen es nicht. Die erste Version von Internet Explorer, die Übergänge überhaupt unterstützt, war IE 10, die sie ohne Fix unterstützt.)
Aber das ist nur Stil und das ist das Einfache. Wenn Sie versuchen, diese Klasse zu verwenden, stoßen Sie auf eine Falle. Die Falle ist, dass Code wie dieser nicht so funktioniert, wie Sie es naiv erwarten könnten:
// 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')
Naiv könnte man denken, dass die Änderung der Höhe nicht animiert wird, da dies geschieht, während die Klasse 'notransition' angewendet wird. In Wirklichkeit aber ist es werden animiert werden, zumindest in allen modernen Browsern habe ich versucht. Das Problem ist, dass der Browser die Stiländerungen zwischenspeichert, die er vornehmen muss, bis das JavaScript vollständig ausgeführt wird, und dann alle Änderungen in einem einzigen Reflow vornimmt. Infolgedessen wird ein Reflow durchgeführt, bei dem sich nicht netto ändert, ob Übergänge aktiviert sind oder nicht, sondern die Höhe netto geändert wird. Folglich wird die Höhenänderung animiert.
Sie könnten denken, ein vernünftiger und sauberer Weg, um dies zu umgehen, wäre, das Entfernen der 'notransition'-Klasse in eine Zeitüberschreitung von 1 ms wie folgt einzuschließen:
// 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);
aber das funktioniert auch nicht zuverlässig. Ich konnte den obigen Code in WebKit-Browsern nicht brechen, aber auf Firefox (sowohl auf langsamen als auch auf schnellen Computern) wird manchmal (scheinbar zufällig) das gleiche Verhalten wie bei der Verwendung des naiven Ansatzes angezeigt. Ich denke, der Grund dafür ist, dass die JavaScript-Ausführung möglicherweise so langsam ist, dass die Timeout-Funktion auf die Ausführung wartet, wenn der Browser inaktiv ist, und ansonsten über einen opportunistischen Reflow nachdenken würde. Wenn dieses Szenario eintritt, Firefox führt die Funktion in der Warteschlange vor dem Reflow aus.
Die einzige Lösung, die ich für das Problem gefunden habe, besteht darin , einen Reflow des Elements zu erzwingen und die daran vorgenommenen CSS-Änderungen zu löschen, bevor die Klasse 'notransition' entfernt wird. Es gibt verschiedene Möglichkeiten, dies zu tun - siehe hier für einige. Das, was einer Standardmethode am nächsten kommt, ist das Lesen der offsetHeight
Eigenschaft des Elements.
Eine Lösung, die tatsächlich funktioniert, ist
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
Hier ist eine JS-Geige, die die drei möglichen Ansätze veranschaulicht, die ich hier beschrieben habe (sowohl den einen erfolgreichen als auch die beiden erfolglosen):
http://jsfiddle.net/2uVAA/131/