Anda ingin mendengarkan acara "akhir" dari transisi.
// d3 v5
d3.select("#myid").transition().style("opacity","0").on("end", myCallback);
// old way
d3.select("#myid").transition().style("opacity","0").each("end", myCallback);
- Demo ini menggunakan acara "akhir" untuk merangkai banyak transisi secara berurutan.
- Contoh donat yang dikirimkan dengan D3 juga menggunakan ini untuk menyatukan beberapa transisi.
- Inilah demo saya sendiri yang mengubah gaya elemen di awal dan akhir transisi.
Dari dokumentasi untuk transition.each([type],listener)
:
Jika jenisnya ditentukan, tambahkan listener untuk peristiwa transisi, yang mendukung peristiwa "mulai" dan "akhir". Listener akan dipanggil untuk setiap elemen individu dalam transisi, meskipun transisi memiliki penundaan dan durasi yang konstan. Peristiwa awal dapat digunakan untuk memicu perubahan seketika saat setiap elemen mulai melakukan transisi. Acara akhir dapat digunakan untuk memulai transisi multi-tahap dengan memilih elemen saat ini this
, dan mendapatkan transisi baru. Setiap transisi yang dibuat selama acara akhir akan mewarisi ID transisi saat ini, sehingga tidak akan menimpa transisi yang lebih baru yang telah dijadwalkan sebelumnya.
Lihat utas forum ini tentang topik untuk lebih jelasnya.
Terakhir, perhatikan bahwa jika Anda hanya ingin menghapus elemen setelah memudar (setelah transisi selesai), Anda dapat menggunakan transition.remove()
.
d3.selectAll()
(bukan setelah setiap elemen selesai)? Dengan kata lain, saya hanya ingin memanggil kembali satu fungsi setelah semua elemen selesai bertransisi..each
pendengar acara, maupun"end"
acara. Sepertinya tidak ada transisi "rantai". Tautan kedua menunjuk ke github yang tidak memuat untuk saya.Solusi Mike Bostock untuk v3 dengan pembaruan kecil:
sumber
if (transition.size() === 0) { callback(); }
function endall(transition, callback){ if(!callback) return; // ... }
atau, karena itu adalah kesalahan yang paling pasti untuk memanggil fungsi ini tanpa callback, melempar lapisan pengecualian ke menjadi cara yang tepat untuk menangani situasi Saya rasa kasus ini tidak perlu terlalu rumit Pengecualianfunction endall(transition, callback){ if(!callback) throw "Missing callback argument!"; // .. }
enter()
dan terpisahexit()
, dan ingin menunggu sampai ketiganya selesai, kita perlu memasukkan kode di callback untuk memastikan itu telah dipanggil tiga kali, bukan? D3 sangat berantakan! Saya berharap saya memilih perpustakaan lain.Sekarang, di d3 v4.0, ada fasilitas untuk secara eksplisit melampirkan event handler ke transisi:
https://github.com/d3/d3-transition#transition_on
Untuk mengeksekusi kode ketika transisi telah selesai, yang Anda butuhkan hanyalah:
sumber
transition.remove()
( tautan ), yang menangani kasus penggunaan umum untuk mentransisikan elemen dari tampilan: `" Untuk setiap elemen yang dipilih, menghapus elemen saat transisi berakhir, selama elemen tersebut tidak memiliki transisi aktif atau tertunda lainnya. Jika elemen memiliki transisi aktif atau tertunda lainnya, tidak melakukan apa pun. "Pendekatan yang sedikit berbeda yang juga berfungsi saat ada banyak transisi dengan banyak elemen yang masing-masing berjalan secara bersamaan:
sumber
Berikut ini adalah versi lain dari solusi Mike Bostock dan terinspirasi oleh komentar @hughes untuk jawaban @ kashesandr. Itu membuat panggilan balik tunggal
transition
di akhir.Diberikan
drop
fungsi ...... kita dapat memperpanjang
d3
seperti ini:Sebagai JSFiddle .
Penggunaan
transition.end(callback[, delayIfEmpty[, arguments...]])
:... atau dengan penundaan opsional jika
transition
kosong:... atau dengan
callback
argumen opsional :d3.transition.end
akan menerapkan luluscallback
bahkan dengan kosongtransition
jika jumlah milidetik ditentukan atau jika argumen kedua benar. Ini juga akan meneruskan argumen tambahan apa pun kecallback
(dan hanya argumen itu). Yang penting, ini tidak akan secara default menerapkancallback
jikatransition
kosong, yang mungkin merupakan asumsi yang lebih aman dalam kasus seperti itu.sumber
Mulai D3 v5.8.0 +, sekarang ada cara resmi untuk melakukan ini menggunakan
transition.end
. Dokumennya ada di sini:https://github.com/d3/d3-transition#transition_end
Contoh kerja dari Bostock ada di sini:
https://observablehq.com/@d3/transition-end
Dan ide dasarnya adalah hanya dengan menambahkan
.end()
, transisi akan mengembalikan janji yang tidak akan terselesaikan hingga semua elemen selesai ditransisikan:Lihat catatan rilis versi untuk lebih banyak lagi:
https://github.com/d3/d3/releases/tag/v5.8.0
sumber
Solusi Mike Bostock ditingkatkan dengan kashesandr + meneruskan argumen ke fungsi callback:
sumber
Sebenarnya ada satu cara lagi untuk melakukan ini menggunakan pengatur waktu.
sumber
Saya memecahkan masalah serupa dengan mengatur durasi transisi menggunakan variabel. Kemudian saya biasa
setTimeout()
memanggil fungsi selanjutnya. Dalam kasus saya, saya ingin sedikit tumpang tindih antara transisi dan panggilan berikutnya, seperti yang akan Anda lihat dalam contoh saya:sumber