LogicFlow icon indicating copy to clipboard operation
LogicFlow copied to clipboard

[Bug Report]: 节点连线后首次选中节点快捷键无效

Open fy-store opened this issue 4 months ago • 5 comments

发生了什么?

拖出两个节点, 对节点连线, 然后鼠标不移出节点, 点击选中节点, 可见点击事件有触发, 按键盘快捷键,无效(Back 删除节点) 点击后鼠标移动再次点击,则键盘快捷键有效有效 示例代码: https://codesandbox.io/p/devbox/pedantic-sunset-62fp69

logicflow/core版本

2.0.16

logicflow/extension版本

2.0.21

logicflow/engine版本

No response

浏览器&环境

Chrome

fy-store avatar Aug 04 '25 10:08 fy-store

遇到同样的问题,这个问题解决了吗

modstart avatar Sep 14 '25 06:09 modstart

遇到同样的问题,Firefox下正常,Chromium内核的会复现。快捷键的监听函数绑定在container上,看样子是点击svg内的节点,第一下点击时svg元素时,document.activeElement元素居然是body,第二下再点击active的是svg中g元素。而Firefox是始终是container元素。

mzleman avatar Nov 05 '25 08:11 mzleman

排查了几天,发现了这个问题的原因

源码中,BaseNode的toFront方法会改变节点的dom顺序(因为svg中的元素只能通过修改同级中的顺序,而非z-index,改变谁在上、谁在下)。 而Chrome支持svg中的g元素获取焦点,点击g元素时,可以通过document.activeElement查看到当前获取到焦点的就是BaseNode的最外层g元素,从而focus事件可以冒泡到logicflow实例的container,从而触发快捷键。 但是如果diff算法判断出的当前获取到焦点的元素需要在点击后发生移动,即调用parent.insertBefore(curElm, refElm),浏览器的行为是取消该元素的焦点选择, 而Firefox当前是不支持g元素获取焦点的,不管怎么点击BaseNode,可以看到document.activeElement永远是logicflow实例的Container。

解决办法:

为节点添加事件监听,推荐绑定 node:focus,主动让logicflow的container获取焦点。

    lf.on('node:focus', (_e) => {
      lf.container.focus();
    });

@fy-store @modstart

mzleman avatar Nov 10 '25 02:11 mzleman

排查了几天,发现了这个问题的原因

源码中,BaseNode的toFront方法会改变节点的dom顺序(因为svg中的元素只能通过修改同级中的顺序,而非z-index,改变谁在上、谁在下)。 而Chrome支持svg中的g元素获取焦点,点击g元素时,可以通过document.activeElement查看到当前获取到焦点的就是BaseNode的最外层g元素,从而focus事件可以冒泡到logicflow实例的container,从而触发快捷键。 但是如果diff算法判断出的当前获取到焦点的元素需要在点击后发生移动,即调用parent.insertBefore(curElm, refElm),浏览器的行为是取消该元素的焦点选择, 而Firefox当前是不支持g元素获取焦点的,不管怎么点击BaseNode,可以看到document.activeElement永远是logicflow实例的Container。

解决办法:

为节点添加事件监听,推荐绑定 node:focus,主动让logicflow的container获取焦点。

    lf.on('node:focus', (_e) => {
      lf.container.focus();
    });

@fy-store @modstart

十分感谢,这个问题也困扰了我很久,Edge也存在相同的问题,所以在除了监听node的focus事件外,还需要监听edge的focus事件。

zzc-1024 avatar Dec 11 '25 08:12 zzc-1024

排查了几天,发现了这个问题的原因

源码中,BaseNode的toFront方法会改变节点的dom顺序(因为svg中的元素只能通过修改同级中的顺序,而非z-index,改变谁在上、谁在下)。 而Chrome支持svg中的g元素获取焦点,点击g元素时,可以通过document.activeElement查看到当前获取到焦点的就是BaseNode的最外层g元素,从而focus事件可以冒泡到logicflow实例的container,从而触发快捷键。 但是如果diff算法判断出的当前获取到焦点的元素需要在点击后发生移动,即调用parent.insertBefore(curElm, refElm),浏览器的行为是取消该元素的焦点选择, 而Firefox当前是不支持g元素获取焦点的,不管怎么点击BaseNode,可以看到document.activeElement永远是logicflow实例的Container。

解决办法:

为节点添加事件监听,推荐绑定 node:focus,主动让logicflow的container获取焦点。

    lf.on('node:focus', (_e) => {
      lf.container.focus();
    });

@fy-store @modstart

感谢,节点已经正常工作。同样连线也有首次快捷键失效的问题,可使用下面的代码。

lf.on('edge:focus', () => {
    lf.container.focus();
});

modstart avatar Dec 12 '25 07:12 modstart