Я пытаюсь применить предложение это, чтобы поймать конец нескольких переходов.
Но в моем локальном файле я получаю ошибку Uncaught TypeError: t.call is not a function
. Код выглядит следующим образом:
var svg = d3.select('svg');
function endall(transition, callback) {
if (typeof callback !== "function") throw new Error("Wrong callback in endall");
if (transition.size() === 0) { callback() }
var n = 0;
transition
.each(function() { ++n; })
.each("end", function() { if (!--n) callback.apply(this, arguments); });
}
for (var i=0;i<5;i++) {
svg.append('rect')
.attr("x",i*60)
.attr("y",50)
.attr("height",50)
.attr("width",50)
.style("fill","#ff0000");
}
svg.selectAll("rect:not(.active)")
.transition()
.duration(1000)
.style("fill","#00ff00")
.call(endall, function() { alert("all done") });
Когда я портирую его на jsfiddle с использованием шаблона D3, он работает хорошо. С другой стороны, когда я портирую его на jsfiddle без шаблона D3, я получаю ту же ошибку.
Видно чего-то не хватает, но что не могу понять.
Скрипка, которая не вызывает ошибки, работает на v3, а та, которая действительно работает, на v5.
В d3v3 вы можете использовать transition.each("end",...)
для событий:
transition.each([type, ]listener)
If type is specified, adds a listener for transition events, supporting "start", "end" and "interrupt" events. The listener will be invoked for each individual element in the transition. (v3 docs)
В d3v4 и v5 этот метод был заменен на transition.on("end",...)
для событий:
selection.on(typenames[, listener[, options]]) <>
Adds or removes a listener to each selected element for the specified event typenames. (current docs)
transition.each(function)
по-прежнему можно использовать для выполнения действия над каждым элементом, в котором выполняется переход, но нельзя использовать для прослушивания событий. Из-за этого изменения между версиями вы получаете сообщение об ошибке: t.call не является функцией (это строка: "end"
), и предупреждение никогда не срабатывает.
Для d3v4 или d3v5 вместо этого используйте:
transition
.each(function() { ++n; })
.on("end", function() { if (!--n) callback.apply(this, arguments); });
Основные версии очень важны для библиотек javascript, и, по-видимому, jsfiddle не поддерживает их в массовом порядке (собирался опубликовать гораздо менее подробный ответ, аналогичный вашему, браво, победив меня как минимум на 3 минуты: ))