为什么在进入/离开SVG的子元素时会触发mouseenter/mouseleave事件?

7

我有一个SVG,其中包含更多的SVG,这些SVG内部有可变数量的矩形元素,所有这些元素都是从数据对象生成的。以下是一般的层次结构:

<svg class="parent-svg">
    <svg class="child-svg">
        <rect />
        <rect />
    </svg>
    <svg class="child-svg">
        <rect />
        <rect />
    </svg>
</svg>

我已将mouseenter/mouseleave事件绑定到.child-svg元素,但我发现当我的鼠标进入/离开

你用的是什么浏览器?对我来说它似乎有期望的效果。 - musicnothing
3
了解事件传播:https://dev59.com/4W445IYBdhLWcg3w9Oss - Givi
这真的是SVG-in-SVG而不是<g>吗? - Kornel
@AlexMorrise:我在Chrome、Firefox和Safari上都试过了...但它在任何一个浏览器上都无法工作。你用的是哪个浏览器? - 3cheesewheel
@porneL:是的,它肯定是SVG-in-SVG。我尝试使用<g>,似乎mouseenter事件处理程序绑定到了其每个子元素,这不是我想要的。 - 3cheesewheel
1个回答

8
我猜测.child-svg没有自己的区域,因此无法直接悬停在它上面。当鼠标离开<rect>时,它也会离开.child-svg
SVG没有流式布局,因此子元素不会影响父元素的大小。
以下是解决方案:http://jsfiddle.net/gMXuU/4/
  • 添加一个没有填充的<rect>作为背景
  • 添加pointer-events:all使不可见元素对鼠标指针“可见”

2
<svg> 元素是容器,本身没有可点击区域(如果它们具有实心背景,例如使用 viewport-fill 属性,则会发生变化)。 - Erik Dahlström
1
我有一个更简单的情况... 一个显示子SVG的DIV。 我为DIV设置了mouseenter,mouseleave和click处理程序,但是SVG会在DIV上引发不必要的mouseleave和mouseenter事件。 在阅读Kornel的答案后,我发现将样式pointer-events:none应用于SVG可以防止不需要的行为。 换句话说,SVG从鼠标的角度看不再存在。 完美! 感谢Kornel关于“pointer-events”的提示! - Bob Arlof
谢谢您的回答。pointer-events拯救了我。我遇到了这个奇怪的 bug,当指针仍然停留在元素上时,mouseleave 会被触发。这个答案帮助我发现这是因为容器根据滚动情况不断地切换其 pointer-events 属性。 - Amber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接