D3操作SVG元素时focus、blur等事件无效?有没有可行替代方案?
可行替代方案
方案1:给SVG元素开启可聚焦属性,直接使用blur事件
SVG元素默认不具备聚焦能力,因此blur、focusout事件无法触发,你只需要给元素添加两个属性即可解决该问题:
- 给矩形所在的
g元素添加tabindex="0"属性,让元素进入页面的Tab聚焦序列 - 添加
focusable="true"属性兼容旧版浏览器的SVG聚焦规则
示例代码如下:
let whiteRect = node.append("g") .attr("tabindex", 0) .attr("focusable", "true") .on('click', function(event, d) { // 点击时主动聚焦当前元素,确保后续失焦事件能正常触发 this.focus(); // 此处添加矩形放大、插入输入框的逻辑 }) .on('blur', function(event, d) { // 如果失焦对象是弹出的输入框,可以加判断跳过复原:if(event.relatedTarget?.tagName !== 'INPUT') // 此处添加矩形缩回、移除输入框的逻辑 });
如果需要避免点击输入框时触发矩形失焦,只需要加一行逻辑判断blur事件的关联目标是否为输入框即可。
方案2:一次性全局事件监听(无需维护全局状态)
如果你不想调整元素的聚焦属性,也可以用更轻量的一次性事件绑定实现需求,不需要提前给整个SVG绑定事件:
let whiteRect = node.append("g") .on('click', function(event, d) { // 阻止事件冒泡,避免直接触发全局点击事件 event.stopPropagation(); // 此处添加矩形放大、插入输入框的逻辑 // 绑定一次性全局点击事件,触发后自动销毁 const handleOuterClick = (e) => { // 判断点击目标不在当前矩形分组内时执行复原 if (!this.contains(e.target)) { // 此处添加矩形缩回、移除输入框的逻辑 document.removeEventListener('click', handleOuterClick); } }; document.addEventListener('click', handleOuterClick); });
该方案每次点击矩形时才会绑定全局事件,执行完复原逻辑后自动销毁监听,性能开销极低,逻辑也很简洁。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

