Jawaban singkat
Gunakan CSS ini:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
Ditambah JS ini (tanpa 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
Atau JS ini dengan jQuery ...
$someElement.addClass('notransition'); // Disable transitions
doWhateverCssChangesYouWant($someElement);
$someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes
$someElement.removeClass('notransition'); // Re-enable transitions
... atau kode yang setara menggunakan pustaka atau kerangka kerja apa pun yang Anda gunakan.
Penjelasan
Ini sebenarnya masalah yang cukup halus.
Pertama, Anda mungkin ingin membuat kelas 'notransition' yang dapat Anda terapkan ke elemen untuk mengatur *-transition
atribut CSS mereka none
. Misalnya:
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
(Samping kecil - perhatikan kurangnya -ms-transition
di sana. Anda tidak memerlukannya. Versi pertama dari Internet Explorer yang mendukung transisi sama sekali adalah IE 10, yang mendukungnya tidak diperbaiki.)
Tapi itu hanya gaya, dan sedikit mudah. Ketika Anda datang untuk mencoba dan menggunakan kelas ini, Anda akan menjebak. Perangkapnya adalah bahwa kode seperti ini tidak akan berfungsi seperti yang Anda harapkan secara naif:
// 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')
Secara naif, Anda mungkin berpikir bahwa perubahan ketinggian tidak akan dianimasikan, karena itu terjadi ketika kelas 'notransition' diterapkan. Pada kenyataannya, ini akan dianimasikan, setidaknya di semua browser modern yang saya coba. Masalahnya adalah bahwa browser sedang melakukan caching perubahan styling yang perlu dibuat sampai JavaScript selesai dieksekusi, dan kemudian membuat semua perubahan dalam satu reflow tunggal. Akibatnya, ia melakukan reflow di mana tidak ada perubahan bersih pada apakah transisi diaktifkan atau tidak, tetapi ada perubahan bersih pada ketinggian. Akibatnya, itu menghidupkan perubahan tinggi.
Anda mungkin berpikir cara yang masuk akal dan bersih untuk menyiasatinya adalah dengan membungkus penghapusan kelas 'notransisi' dalam waktu habis 1 ms, seperti ini:
// 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);
tapi ini tidak bisa diandalkan. Saya tidak dapat membuat kode di atas di browser WebKit, tetapi pada Firefox (pada mesin lambat dan cepat) Anda kadang-kadang (tampaknya secara acak) mendapatkan perilaku yang sama dengan menggunakan pendekatan naif. Saya kira alasan untuk ini adalah bahwa eksekusi JavaScript mungkin cukup lambat sehingga fungsi timeout menunggu untuk dieksekusi pada saat browser idle dan sebaliknya berpikir untuk melakukan reflow oportunistik, dan jika skenario itu terjadi, Firefox menjalankan fungsi antrian sebelum reflow.
Satu-satunya solusi yang saya temukan untuk masalah ini adalah memaksa reflow elemen, membersihkan perubahan CSS yang dibuat untuk itu, sebelum menghapus kelas 'notransition'. Ada berbagai cara untuk melakukan ini - lihat di sini untuk beberapa. Hal yang paling dekat dengan cara 'standar' dalam melakukan ini adalah membaca offsetHeight
properti elemen.
Salah satu solusi yang benar-benar berfungsi adalah
someElement.classList.add('notransition'); // Disable transitions
doWhateverCssChangesYouWant(someElement);
someElement.offsetHeight; // Trigger a reflow, flushing the CSS changes
someElement.classList.remove('notransition'); // Re-enable transitions
Berikut ini biola JS yang menggambarkan tiga pendekatan yang mungkin saya jelaskan di sini (baik pendekatan yang berhasil maupun yang gagal):
http://jsfiddle.net/2uVAA/131/