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

Chrome中SVG <use>元素触发目标mouseenter事件,其他事件不触发的解决方法

问题解决:阻止SVG 触发原元素的事件

问题描述

嵌入的SVG内的元素A绑定了mouseenter、mouseleave、click等事件,当使用<use>元素引用该元素A时,在Chrome及Chromium系浏览器中,<use>会触发A的mouseenter事件,但mouseleave、click等事件却不会触发。由于<use>在页面中可能有完全不同的语义,需要阻止这种事件触发行为,同时保留<use>同步原元素修改、动态重定向的特性,避免克隆元素的方案。

演示示例

HTML代码

<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>GUI</title>
</head>

<body style="">
<div id="gui">

<svg height="500" version="1.1" width="500" xmlns="http://www.w3.org/2000/svg">
  <ellipse cx="100" cy="100" rx="50" ry="50" id="circ"></ellipse>
  <use href="#circ" x="200"></use>
</svg>

</div>
</body></html>

JavaScript代码

let circle = document.getElementById("circ");

circle.addEventListener("mouseenter",()=>{ // 当鼠标移到<use>上时会触发
    circle.setAttribute("fill", "red")
});

circle.addEventListener("mouseleave",()=>{ // 不会触发
    circle.setAttribute("fill", "black")
});

circle.addEventListener("click",()=>{ // 不会触发
    circle.setAttribute("fill", "green")
});

解决方案

核心思路是在事件回调中,通过composedPath()方法获取事件的传播路径,判断事件是否来自<use>创建的影子DOM实例,若是则终止事件处理。

修改后的JavaScript代码如下:

let circle = document.getElementById("circ");

// 通用判断函数:检查事件是否来自<use>的引用实例
function isFromUseElement(event) {
    const path = event.composedPath();
    // 遍历路径,查找是否存在<use>元素或者影子DOM中的节点
    return path.some(node => {
        return node.tagName === 'USE' || (node.getRootNode && node.getRootNode().host?.tagName === 'USE');
    });
}

circle.addEventListener("mouseenter",(event)=>{
    if (isFromUseElement(event)) return; // 来自<use>则不执行
    circle.setAttribute("fill", "red")
});

circle.addEventListener("mouseleave",(event)=>{
    if (isFromUseElement(event)) return;
    circle.setAttribute("fill", "black")
});

circle.addEventListener("click",(event)=>{
    if (isFromUseElement(event)) return;
    circle.setAttribute("fill", "green")
});

原理说明

  • composedPath()会返回事件传播经过的所有节点,包括影子DOM内的节点。
  • 对于<use>创建的实例,事件路径中要么直接包含<use>元素,要么影子DOM节点的宿主(host)是<use>元素,通过这个特征可以判断事件来源。
  • 这种方法不需要克隆元素,完全保留<use>同步原元素修改、动态切换引用的特性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:43:40