Chcesz nasłuchiwać zdarzenia „końca” przejścia.
// d3 v5
d3.select("#myid").transition().style("opacity","0").on("end", myCallback);
// old way
d3.select("#myid").transition().style("opacity","0").each("end", myCallback);
- To demo wykorzystuje zdarzenie „end” do połączenia wielu przejść w określonej kolejności.
- Przykład pączek , że statki z D3 również używa tego do łańcucha razem wiele przejść.
- Oto moje własne demo , który zmienia styl elementów na początku i na końcu przejścia.
Z dokumentacji transition.each([type],listener)
:
Jeśli określono typ , dodaje detektor zdarzeń przejścia, obsługujący zarówno zdarzenia „start”, jak i „end”. Odbiornik zostanie wywołany dla każdego elementu przejścia, nawet jeśli przejście ma stałe opóźnienie i czas trwania. Zdarzenie początkowe może służyć do wywołania natychmiastowej zmiany, gdy każdy element zaczyna się zmieniać. Zdarzenie końcowe można wykorzystać do zainicjowania przejść wieloetapowych przez wybranie bieżącego elementu this
i wyprowadzenie nowego przejścia. Wszelkie przejścia utworzone podczas zdarzenia końcowego odziedziczą bieżący identyfikator przejścia, a zatem nie zastąpią nowszego przejścia, które było wcześniej zaplanowane.
Więcej informacji znajdziesz w tym wątku na forum na ten temat .
Na koniec zwróć uwagę, że jeśli chcesz po prostu usunąć elementy po ich wyblaknięciu (po zakończeniu przejścia), możesz użyć transition.remove()
.
d3.selectAll()
(zamiast po zakończeniu każdego elementu)? Innymi słowy, chcę po prostu wywołać jedną funkcję, gdy wszystkie elementy zakończą przejście..each
detektora zdarzeń ani"end"
zdarzenia. Wydaje się, że nie łączy to przejść w łańcuch. Drugi link wskazuje na github, który nie ładuje się dla mnie.Mike Bostock za rozwiązaniem dla v3 z małą aktualizację:
źródło
if (transition.size() === 0) { callback(); }
function endall(transition, callback){ if(!callback) return; // ... }
lub, ponieważ wywołanie tej funkcji bez wywołania zwrotnego jest z całą pewnością błędem, rzucenie wyjątku być odpowiednim sposobem radzenia sobie z sytuacją Myślę, że ta sprawa nie wymaga zbyt skomplikowanej Wyjątekfunction endall(transition, callback){ if(!callback) throw "Missing callback argument!"; // .. }
enter()
iexit()
przejścia i chcemy poczekać, aż wszystkie trzy zakończą się, musimy umieścić kod w wywołaniu zwrotnym, aby upewnić się, że został wywołany trzy razy, prawda? D3 jest taki niechlujny! Żałuję, że nie wybrałem innej biblioteki.Teraz w d3 v4.0 istnieje możliwość jawnego dołączania programów obsługi zdarzeń do przejść:
https://github.com/d3/d3-transition#transition_on
Aby wykonać kod po zakończeniu przejścia, potrzebujesz tylko:
źródło
transition.remove()
( link ), który obsługuje typowy przypadek użycia przejścia elementu z widoku: `` Dla każdego wybranego elementu, usuwa element po zakończeniu przejścia, o ile element nie ma innych aktywnych lub oczekujących przejść. element ma inne aktywne lub oczekujące przejścia, nic nie robi. "Nieco inne podejście, które działa również w przypadku wielu przejść, z których każdy działa jednocześnie:
źródło
Poniżej znajduje się kolejna wersja Mike'a Bostocka roztworze i zainspirowany komentarzem @hughes' do użytkownika @ kashesandr odpowiedź. Wykonuje pojedyncze wywołanie zwrotne po
transition
zakończeniu.Dawać
drop
funkcję ...... możemy przedłużyć
d3
sposób:Jako JSFiddle .
Posługiwać się
transition.end(callback[, delayIfEmpty[, arguments...]])
:... lub z opcjonalnym opóźnieniem, jeśli
transition
jest pusty:... lub z opcjonalnymi
callback
argumentami:d3.transition.end
zastosuje przekazaną wartośćcallback
nawet z pustą wartością,transition
jeśli podano liczbę milisekund lub jeśli drugi argument jest prawdziwy. Spowoduje to również przekazanie wszelkich dodatkowych argumentów docallback
(i tylko tych argumentów). Co ważne, domyślnie nie będzie to miało zastosowania,callback
jeśli iftransition
jest puste, co jest prawdopodobnie bezpieczniejszym założeniem w takim przypadku.źródło
Od wersji D3 w wersji 5.8.0 + jest teraz oficjalny sposób na zrobienie tego za pomocą
transition.end
. Dokumenty są tutaj:https://github.com/d3/d3-transition#transition_end
Przykład roboczy firmy Bostock jest tutaj:
https://observablehq.com/@d3/transition-end
Podstawową ideą jest to, że samo dołączenie
.end()
przejścia zwróci obietnicę, która nie zostanie rozwiązana, dopóki wszystkie elementy nie zostaną zakończone:Zobacz informacje o wydaniu wersji, aby dowiedzieć się więcej:
https://github.com/d3/d3/releases/tag/v5.8.0
źródło
Rozwiązanie Mike'a Bostocka ulepszone przez kashesandr + przekazanie argumentów do funkcji zwrotnej:
źródło
Właściwie jest jeszcze jeden sposób na zrobienie tego za pomocą timerów.
źródło
Rozwiązałem podobny problem, ustawiając czas trwania przejść za pomocą zmiennej. Następnie
setTimeout()
wywoływałem następną funkcję. W moim przypadku chciałem, aby przejście między przejściem a następnym połączeniem nieznacznie się pokrywało, jak zobaczysz w moim przykładzie:źródło