d3.js 过渡结束事件
Posted
技术标签:
【中文标题】d3.js 过渡结束事件【英文标题】:d3.js transition end event 【发布时间】:2012-12-11 01:24:48 【问题描述】:我正在对selectAll()
返回的一组节点应用过渡。我认为结束事件会在所有转换完成后触发,但each("end",function)
在每次转换结束时被调用。
那么有没有办法设置一个回调,在所有选定节点的转换完成后调用?
我应该为此使用call
吗?但我没有看到它在文档中的任何地方用作结束回调。
我也可以在each
回调中运行一个计数器。但是有没有办法知道有多少节点仍在等待完成过渡?还是选定节点组中当前节点的索引?
我在链中有两个 select() 调用,例如 selectAll('.partition').selectAll('.subpartition')
因此传递给每个回调的 index 参数将旋转 n 次。
【问题讨论】:
您能否将示例代码发布到 jsfiddle 中? 来自迈克本人 - groups.google.com/forum/#!msg/d3-js/WC_7Xi6VV50/j1HK0vIWI-EJ 谢谢我在找这个。我最终得到了类似的解决方案 Invoke a callback at the end of a transition的可能重复 【参考方案1】:据我所知,没有内置方法可以知道组的最后一次转换何时完成,但有一些方法可以绕过它。我多次使用的一种方法是维护已完成的转换计数。
var n = 0;
d3.selectAll('div')
.each(function() // I believe you could do this with .on('start', cb) but I haven't tested it
n++;
)
.transition()
.on('end', function() // use to be .each('end', function())
n--;
if (!n)
endall();
)
function endall()
// your end function here
以下是相关文档的链接:
https://github.com/d3/d3-transition#control-flow https://github.com/d3/d3-transition#the-life-of-a-transition【讨论】:
在 2016 年的第 4 版中,此代码根本不起作用!将 each("end" 替换为 on("end" @ArslArsl 感谢您的更新。我添加了指向正确文档的链接并将代码更新到 2016 版本。【参考方案2】:这里有一个干净的方式来完成你想要的:
function endAll (transition, callback)
var n;
if (transition.empty())
callback();
else
n = transition.size();
transition.each("end", function ()
n--;
if (n === 0)
callback();
);
然后您可以像这样轻松调用此函数:
selection.transition()
.call(endAll, function ()
console.log("All the transitions have ended!");
);
即使转换为空,这也会起作用。
【讨论】:
请注意,您不能在“结束”事件上绑定两个函数:transition.each("end", f1).each("end", f2)
将只调用f2
。因此,如果在同一转换中使用 .each("end", ...)
,则不应使用 endAll
。【参考方案3】:
我有同样的问题
每个元素都会执行回调
我已经解决了使用下划线一次的方法
http://underscorejs.org/#once
d3.select("#myid")
.transition()
.style("opacity","0")
.each("end", _.once(myCallback) );
【讨论】:
他们在询问 selectAll。 select 只返回一个元素 这个答案没有回答问题。它只会运行一次,但不一定会在所有转换完成后运行。这是一个重要的区别,因为同一选择中的过渡可能具有不同的长度。例如duration(function(d,i) return 100 * i;)
以上是关于d3.js 过渡结束事件的主要内容,如果未能解决你的问题,请参考以下文章