Krótka odpowiedź
Użyj tego CSS:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
Plus ten JS (bez 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
Lub ten JS z jQuery ...
$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass('notransition'); // Re-enable transitions
... lub równoważny kod przy użyciu dowolnej innej biblioteki lub frameworka, z którym pracujesz.
Wyjaśnienie
To właściwie dość subtelny problem.
Po pierwsze, prawdopodobnie chcesz utworzyć klasę „notransition”, którą możesz zastosować do elementów, aby ustawić ich *-transitionatrybuty CSS none. Na przykład:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
(Drobny na bok - zauważ brak -ms-transitiontam. Nie potrzebujesz go. Pierwszą wersją Internet Explorera do obsługi przejść w ogóle była IE 10, która obsługiwała je bez prefiksu).
Ale to tylko styl i to jest łatwe. Kiedy spróbujesz skorzystać z tej klasy, wpadniesz w pułapkę. Pułapka polega na tym, że taki kod nie będzie działał w sposób, jakiego można naiwnie oczekiwać:
// 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')
Naiwnie możesz pomyśleć, że zmiana wysokości nie będzie animowana, ponieważ dzieje się tak, gdy stosowana jest klasa „notransition”. Jednak w rzeczywistości będzie animowany, przynajmniej we wszystkich nowoczesnych przeglądarkach, które wypróbowałem. Problem polega na tym, że przeglądarka buforuje zmiany stylu, które musi wprowadzić, aż JavaScript zakończy wykonywanie, a następnie dokonuje wszystkich zmian w jednym przepływie. W wyniku tego następuje ponowne wlanie, w którym nie ma zmiany siatki określającej, czy przejścia są włączone, ale występuje zmiana wysokości netto. W związku z tym animuje zmianę wysokości.
Można pomyśleć, że rozsądnym i czystym sposobem na obejście tego byłoby ominięcie usunięcia klasy „notransition” w czasie 1 ms, jak poniżej:
// 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);
ale to też nie działa niezawodnie. Nie udało mi się złamać powyższego kodu w przeglądarkach WebKit, ale w Firefoksie (zarówno na powolnych, jak i szybkich komputerach) czasami (pozornie przypadkowo) dostajesz takie samo zachowanie jak naiwne podejście. Wydaje mi się, że powodem jest to, że wykonanie JavaScript może być na tyle powolne, że funkcja limitu czasu czeka na wykonanie do czasu, gdy przeglądarka jest bezczynna, i w przeciwnym razie pomyślałaby o oportunistycznym przepełnieniu, a jeśli tak się stanie, Firefox wykonuje funkcję w kolejce przed ponownym zalaniem.
Jedynym rozwiązaniem, jakie znalazłem dla tego problemu, jest wymuszenie ponownego wlewania elementu, opróżnienie dokonanych w nim zmian CSS, przed usunięciem klasy „notransition”. Można to zrobić na wiele sposobów - zobacz tutaj . Najbliższą „standardową” metodą jest odczytanie offsetHeightwłaściwości elementu.
Jednym z faktycznie działających rozwiązań jest
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
Oto skrzypce JS, które ilustrują trzy możliwe podejścia, które tu opisałem (zarówno jedno udane, jak i dwa nieudane):
http://jsfiddle.net/2uVAA/131/