Saya memiliki elemen DOM dengan beberapa / semua efek berikut diterapkan:
#elem {
-webkit-transition: height 0.4s ease;
-moz-transition: height 0.4s ease;
-o-transition: height 0.4s ease;
transition: height 0.4s ease;
}
Saya menulis plugin jQuery yang mengubah ukuran elemen ini, saya harus menonaktifkan efek ini sementara sehingga saya dapat mengubah ukurannya dengan lancar.
Apa cara paling elegan untuk menonaktifkan efek ini sementara (dan kemudian mengaktifkannya kembali), mengingat mereka dapat diterapkan dari orang tua atau mungkin tidak diterapkan sama sekali.
javascript
jquery
css
Sam Saffron
sumber
sumber
.notransition
kelas. Akan lebih masuk akal untuk melakukannya sebaliknya, yaitu target#elem.yestransition
dengan css Anda dan menghapus kelas ini. Itu menghilangkan memiliki jahat*
di css Anda.Jawaban:
Jawaban singkat
Gunakan CSS ini:
Ditambah JS ini (tanpa jQuery) ...
Atau JS ini dengan jQuery ...
... 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 merekanone
. Misalnya:(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:
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:
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
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/
sumber
Saya akan menganjurkan penonaktifan animasi seperti yang disarankan oleh DaneSoul, tetapi membuat perubahan global:
.notransition
kemudian dapat diterapkan kebody
elemen, secara efektif mengesampingkan setiap animasi transisi pada halaman:sumber
Tambahkan kelas CSS tambahan yang memblokir transisi, dan kemudian hapus untuk kembali ke keadaan sebelumnya. Ini membuat kode CSS dan JQuery pendek, sederhana dan mudah dipahami.
CSS :
!important
ditambahkan untuk memastikan bahwa aturan ini akan memiliki lebih banyak "bobot", karena ID biasanya lebih spesifik daripada kelas.JQuery :
sumber
Untuk solusi JS murni (tanpa kelas CSS), cukup atur
transition
ke'none'
. Untuk mengembalikan transisi seperti yang ditentukan dalam CSS, seteltransition
ke string kosong.Jika Anda menggunakan awalan vendor, Anda harus mengaturnya juga.
sumber
Anda dapat menonaktifkan animasi, transisi, trasforms untuk semua elemen di halaman dengan kode css ini
sumber
Saya pikir Anda bisa membuat kelas css terpisah yang dapat Anda gunakan dalam kasus ini:
Kemudian di jQuery Anda akan beralih kelas seperti:
sumber
Jika Anda ingin solusi tanpa jquery sederhana untuk mencegah semua transisi:
sumber
Jika Anda ingin menghapus transisi, transformasi, dan animasi CSS dari halaman web saat ini, Anda bisa menjalankan skrip kecil yang saya tulis ini (di dalam konsol browser Anda):
Ini menggunakan vanillaJS untuk memuat file css ini . Ini juga repo github jika Anda ingin menggunakan ini dalam konteks scraper (Ruby-Selenium): remove-CSS-animations-repo
sumber
tidak
di js kamu membunuhnya?
jelas ulangi untuk masing-masing.
sumber
Saya memiliki kelas di CSS Anda seperti ini:
dan kemudian di jQuery Anda:
sumber
#elem.no-transition
CSS Anda, Anda baru saja menargetkan.no-transition
. Mungkin Anda bermaksud menulis#elem.no-transition
di CSS Anda?