检测多个重叠SVG元素上的鼠标事件

时间:2015-03-31 19:57:02

标签: javascript svg event-propagation pointer-events

我正在尝试检测部分重叠的SVG元素上的mousemove事件,如此图像

enter image description here

fiddle

<svg>
    <rect id="red"    x=10 y=10 width=60 height=60 style="fill:#ff0000" />
    <rect id="orange" x=80 y=10 width=60 height=60 style="fill:#ffcc00" />
    <rect id="blue"   x=50 y=30 width=60 height=60 style="fill:#0000ff; fill-opacity: 0.8" />
</svg>

$('rect').on('mousemove', function()
{
    log(this.id);
});

现在,当鼠标悬停在蓝色/红色交叉点上时,我想检测这两个元素上的鼠标事件,蓝色/橙色组合则相同。正如您在日志中看到的那样,在这些情况下,事件目前仅针对蓝色框被触发,因为它位于顶部。

这与指针事件有关,因为我可以使用红色和橙色元素来触发事件,同时将setting the blue element's pointer-events to none悬停在蓝色元素上。但后来我没有得到蓝盒子的事件,所以这也不是一个可行的选择。

我将使用哪个库解决此问题。我在this d3 example中查看事件冒泡,但这仅适用于嵌套在DOM中的元素。我有很多可能与许多其他元素重叠的独立元素,因此无法以这种方式构建我的DOM。

我猜最后的办法是找到当前鼠标位置的元素,然后手动触发事件。因此,我查看document.elementFromPoint(),但这只会产生1个元素(并且在SVG中可能不起作用?)。我找到了jQuerypp函数within,它找到了给定位置的元素,请参阅here。这个例子看起来很棒,除了它是DIV而不是SVG内部。当用svg矩形元素替换div时,小提琴似乎是break

我该怎么办?!

1 个答案:

答案 0 :(得分:5)

这里的好评为我提供了答案:可以通过在光标位置使用getIntersectionList()查找事件来手动将事件传播到基础元素。

$('svg').on('mousemove', function(evt)
{
    var root = $('svg')[0];
    var rpos = root.createSVGRect();
    rpos.x = evt.clientX;
    rpos.y = evt.clientY;
    rpos.width = rpos.height = 1;
    var list = root.getIntersectionList(rpos, null);

    for(var i = 0; i < list.length; i++)
    {
        if(list[i] != evt.target)
        {
            $(list[i]).mousemove();
        }
    }
});

工作示例:http://jsfiddle.net/michaschwab/w0wufbtn/6/

如果其他听众需要原始事件对象,请查看http://jsfiddle.net/michaschwab/w0wufbtn/13/

非常感谢!!