d3节点单击双击事件使用场景&区分方法(mouseup失效+定时器解决)

假如我有一个知识图谱(如下图),我希望单击节点的时候触发事件1,双击节点的时候触发事件2,(比如单击我希望看到节点的详细信息,双击我希望获得节点的子图)。
实现的比较简单,是使用d3提供的节点监听事件,但是浏览器在判断是否是 dblclick 时,往往会先触发 click 事件,再触发 dblclick 事件。这就导致触发双击事件的时候一定会有 单击事件。我的解决方法是定时器。
在这里插入图片描述

首先补充一个错误做法,mouseup失效

这个应该是d3的drag事件(不太确定,但反正是d3中的其他事件)覆盖了mouseup, mouseup无法触发(console.log没有打印),区分失败。

  const nodeGroup = svg
  .append("g")
  .selectAll("g")
  .data(nodes)
  .join("g")
  .attr("class", "node-group")
  .on("mousedown", (event, d) => {
    isDoubleClick = false;
  })
  .on("mouseup", (event, d) => {
    if (isDoubleClick) return; // 如果是双击,忽略单击逻辑
    nodeClick(d); // 单击逻辑
    setSelectedElement({ type: "node", data: d });
  })
  .on("dblclick", (event, d) => {
    isDoubleClick = true; // 标记为双击
    handleNodeDoubleClick(d); // 执行双击逻辑
  })

定时器区分

通过设置一个短暂的定时器,延迟处理单击事件。如果在延迟期间检测到双击,就取消单击逻辑。

    let clickTimer = null;
    // 绘制节点分组,支持叠加圆形和图标
    const nodeGroup = svg
    .append("g")
    .selectAll("g")
    .data(nodes)
    .join("g")
    .attr("class", "node-group")
    .on("click", (event, d) => {
      // 如果已经触发双击,则忽略单击
      if (clickTimer) {
        clearTimeout(clickTimer);
        clickTimer = null;
      }
      // 设置定时器,延迟执行单击逻辑
      clickTimer = setTimeout(() => {
        nodeClick(d); // 单击逻辑
        setSelectedElement({ type: "node", data: d });
        clickTimer = null; // 清空定时器
      }, 300); // 300ms 是浏览器区分单击和双击的常见延迟
    })
    .on("dblclick", (event, d) => {
      // 清空单击定时器
      if (clickTimer) {
        clearTimeout(clickTimer);
        clickTimer = null;
      }
      // 执行双击逻辑
      handleNodeDoubleClick(d);
    })

这个方法个人感受不太优秀的点在,延迟太长了。

当然不一定要使用单击和双击触发节点的筛选/信息, 可以用其他方法触发两个事件

这些理论上都可以:

右键操作
键盘快捷键
按钮或图标
长按操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值