我需要使用D3.js制作一个 FadeOut 方法(类似于 jQuery)。我需要做的是使用transition()
.
d3.select("#myid").transition().style("opacity", "0");
问题是我需要一个回调来实现转换完成的时间。如何实现回调?
我需要使用D3.js制作一个 FadeOut 方法(类似于 jQuery)。我需要做的是使用transition()
.
d3.select("#myid").transition().style("opacity", "0");
问题是我需要一个回调来实现转换完成的时间。如何实现回调?
您想监听转换的“结束”事件。
// 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
和派生新转换来启动多阶段转换。在结束事件期间创建的任何过渡都将继承当前的过渡 ID,因此不会覆盖先前安排的较新的过渡。
有关更多详细信息,请参阅有关该主题的论坛主题。
最后,请注意,如果您只想在元素淡出后(过渡完成后)移除它们,您可以使用transition.remove()
.
迈克·博斯托克的解决方案为V3的小更新:
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); });
}
d3.selectAll("g").transition().call(endall, function() { console.log("all done") });
现在,在 d3 v4.0 中,有一个工具可以显式地将事件处理程序附加到转换:
https://github.com/d3/d3-transition#transition_on
要在转换完成时执行代码,您只需要:
d3.select("#myid").transition().style("opacity", "0").on("end", myCallback);
一种稍微不同的方法也适用于有许多转换且每个元素同时运行的情况:
var transitions = 0;
d3.select("#myid").transition().style("opacity","0").each( "start", function() {
transitions++;
}).each( "end", function() {
if( --transitions === 0 ) {
callbackWhenAllIsDone();
}
});
以下是 Mike Bostock解决方案的另一个版本,其灵感来自 @hughes 对 @kashesandr 回答的评论。它在transition
's 结束时进行单个回调。
给定一个drop
函数...
function drop(n, args, callback) {
for (var i = 0; i < args.length - n; ++i) args[i] = args[i + n];
args.length = args.length - n;
callback.apply(this, args);
}
...我们可以d3
像这样扩展:
d3.transition.prototype.end = function(callback, delayIfEmpty) {
var f = callback,
delay = delayIfEmpty,
transition = this;
drop(2, arguments, function() {
var args = arguments;
if (!transition.size() && (delay || delay === 0)) { // if empty
d3.timer(function() {
f.apply(transition, args);
return true;
}, typeof(delay) === "number" ? delay : 0);
} else { // else Mike Bostock's routine
var n = 0;
transition.each(function() { ++n; })
.each("end", function() {
if (!--n) f.apply(transition, args);
});
}
});
return transition;
}
使用transition.end(callback[, delayIfEmpty[, arguments...]])
:
transition.end(function() {
console.log("all done");
});
... 或者如果transition
为空则有一个可选的延迟:
transition.end(function() {
console.log("all done");
}, 1000);
...或带有可选callback
参数:
transition.end(function(x) {
console.log("all done " + x);
}, 1000, "with callback arguments");
d3.transition.end
如果指定了毫秒数或第二个参数为真,callback
即使为空,也将应用传递的值。这也会将任何其他参数转发给(并且仅这些参数)。重要的是,默认情况下这不会应用if为空,这在这种情况下可能是更安全的假设。transition
callback
callback
transition