Вы хотите прослушать «конечное» событие перехода.
// d3 v5
d3.select("#myid").transition().style("opacity","0").on("end", myCallback);
// old way
d3.select("#myid").transition().style("opacity","0").each("end", myCallback);
Из документации для transition.each([type],listener)
:
Если указан тип , добавляет прослушиватель событий перехода, поддерживающий как «начало», так и «конец». Слушатель будет вызываться для каждого отдельного элемента в переходе, даже если переход имеет постоянную задержку и продолжительность. Событие start может использоваться для запуска мгновенного изменения при переходе каждого элемента. Конечное событие может использоваться для инициирования многоступенчатых переходов путем выбора текущего элемента this
, и создания нового перехода. Любые переходы, созданные во время конечного события, унаследуют текущий идентификатор перехода и, таким образом, не будут отменять более новый переход, который был ранее запланирован.
Смотрите эту ветку форума по теме для получения более подробной информации.
Наконец, обратите внимание, что если вы просто хотите удалить элементы после того, как они исчезли (после завершения перехода), вы можете использовать transition.remove()
.
d3.selectAll()
(а не после завершения каждого элемента)? Другими словами, я просто хочу вызвать одну функцию после того, как все элементы закончат переход..each
прослушиватель событий, ни"end"
событие. Это не похоже на "цепочку" переходов. Вторая ссылка указывает на github, который у меня не загружается.Решение Майка Бостока для v3 с небольшим обновлением:
источник
if (transition.size() === 0) { callback(); }
function endall(transition, callback){ if(!callback) return; // ... }
или, поскольку вызов этой функции без обратного вызова, несомненно, является ошибкой, бросает швы исключения в быть подходящим способом справиться с ситуацией, я думаю, в этом случае не нужно слишком сложное исключениеfunction endall(transition, callback){ if(!callback) throw "Missing callback argument!"; // .. }
enter()
иexit()
переходы, и хотят ждать , пока все три не закончили, мы должны поставить код в функции обратного вызова , чтобы убедиться , что он был вызван в три раза, не так ли? D3 такой беспорядочный! Хотел бы я выбрать другую библиотеку.Теперь в d3 v4.0 есть возможность явно прикреплять обработчики событий к переходам:
https://github.com/d3/d3-transition#transition_on
Все, что вам нужно, чтобы выполнить код после завершения перехода:
источник
transition.remove()
( ссылка ), которая обрабатывает общий вариант использования перехода элемента из представления: «» Для каждого выбранного элемента удаляет элемент по окончании перехода, если у элемента нет других активных или ожидающих переходов. Если элемент имеет другие активные или ожидающие переходы, ничего не делает. "Немного другой подход, который работает также, когда есть много переходов с множеством элементов, каждый из которых выполняется одновременно:
источник
Ниже еще одна версия Майка Босток в растворе и вдохновленный комментарий @hughes' на @ kashesandr отвечают. По
transition
завершении он выполняет один обратный вызов .Учитывая
drop
функцию ...... мы можем расширить
d3
так:Как JSFiddle .
Использование
transition.end(callback[, delayIfEmpty[, arguments...]])
:... или с дополнительной задержкой, если
transition
пусто:... или с необязательными
callback
аргументами:d3.transition.end
будет применять переданное значениеcallback
даже с пустым значением,transition
если указано количество миллисекунд или если второй аргумент истинен. Это также направит любые дополнительные аргументы вcallback
(и только эти аргументы). Важно отметить, что по умолчанию это не будет применяться,callback
еслиtransition
пусто, что, вероятно, является более безопасным предположением в таком случае.источник
Начиная с D3 v5.8.0 +, теперь есть официальный способ сделать это, используя
transition.end
. Документы здесь:https://github.com/d3/d3-transition#transition_end
Рабочий пример от Bostock находится здесь:
https://observablehq.com/@d3/transition-end
И основная идея заключается в том, что просто добавляя
.end()
переход, он вернет обещание, которое не будет выполнено, пока не будут выполнены все элементы перехода:Дополнительные сведения см. В примечаниях к выпуску версии:
https://github.com/d3/d3/releases/tag/v5.8.0
источник
Решение Майка Бостока улучшено за счет kashesandr + передачи аргументов функции обратного вызова:
источник
На самом деле есть еще один способ сделать это с помощью таймеров.
источник
Я решил аналогичную проблему, установив длительность переходов с помощью переменной. Затем я
setTimeout()
вызывал следующую функцию. В моем случае я хотел небольшое перекрытие между переходом и следующим вызовом, как вы увидите в моем примере:источник