You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在D3.js可折叠树中实现指定节点持续闪烁

解决D3.js节点持续闪烁的问题

我一眼就看出问题出在哪啦!你当前的代码有两个关键问题导致只能闪一次:

  • 首先,setInterval(blink(theNode),3000);这行是直接执行了blink函数,把它的返回值(这里是undefined)传给了setInterval,所以定时器根本不会重复触发,只会执行一次。
  • 其次,你的blink函数里的过渡是单向的:从opacity 0变到1,但没有再变回去的逻辑,就算重复调用,节点也只会停在opacity 1的状态,不会真正“闪烁”。

下面是修改后的完整代码,能实现持续闪烁的效果:

$("#search").on("select2:select", function (e) {
  var theNode = d3.selectAll(".node")
    .filter(function (d) { 
      return d.name == e.params.data.text 
    });
  
  // 用匿名函数包裹,确保每次定时器触发时都调用blink
  setInterval(function() {
    blink(theNode);
  }, 3000);
});

function blink(Node) {
  // 做一个完整的闪烁循环:透明→不透明,完成一次闪烁动作
  Node.transition()
    .duration(500)
    .style("opacity", 0)
    .transition()
    .duration(500)
    .style("opacity", 1);
}

如果你想要更流畅的循环闪烁,也可以利用D3的transition结束事件来递归调用,避免依赖setInterval的时间差:

$("#search").on("select2:select", function (e) {
  var theNode = d3.selectAll(".node")
    .filter(function (d) { 
      return d.name == e.params.data.text 
    });
  
  // 启动闪烁循环
  startBlinking(theNode);
});

function startBlinking(Node) {
  function blinkLoop() {
    Node.transition()
      .duration(500)
      .style("opacity", 0)
      .transition()
      .duration(500)
      .style("opacity", 1)
      .on("end", blinkLoop); // 过渡结束后再次调用,形成无限循环
  }
  blinkLoop();
}

关键修改点解释:

  • setInterval的正确用法:用匿名函数包裹blink调用,这样setInterval每次触发时才会执行blink,而不是一开始就执行完。
  • 双向过渡逻辑:让节点先变透明,再变回不透明,完成一次完整的闪烁动作;如果用递归的end事件,能保证每次闪烁的时间完全一致,不会有定时器的累积误差。

内容的提问来源于stack exchange,提问作者yogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:03:39