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 过渡结束事件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 d3 js 中为地图重投影进行平滑过渡

D3.js:动态效果

过渡结束事件

JS过渡结束监听事件及使用自定义事件解决兼容问题的方法

如何规范跨浏览器的 CSS3 过渡结束事件?

transitionend的运用案例