在多个重叠的SVG元素上检测鼠标事件 [英] Detecting Mouse Events on Multiple Overlapping SVG Elements

查看:395
本文介绍了在多个重叠的SVG元素上检测鼠标事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to detect mousemove events on partially overlapping SVG elements, as in this image

小提琴

<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);
});

现在,当将鼠标悬停在蓝色/红色交叉点上时,我想检测这两个元素上的鼠标事件,并且对于蓝色/橙色组合也是如此.正如您在日志中看到的那样,在这种情况下,当前仅针对顶部的蓝色框触发该事件.

Now, when hovering the mouse over the blue/red intersection I'd like to detect mouse events on both those elements, and the same for the blue/orange combo. As you can see in the logs, in those cases the event is currently only fired for the blue box as it is on top.

这与指针事件有关,因为我可以通过

This has to do with pointer-events, as I can get the red and orange elements to fire the event while hovering the blue element by setting the blue element's pointer-events to none. But then I don't get the events for the blue box, so that is not a viable option either.

我将使用解决该问题的任何库.我在此d3示例中查看了事件冒泡,但这仅适用于嵌套的元素在DOM中.我有很多独立的元素,它们可能与许多其他元素重叠,因此无法以这种方式构造我的DOM.

I will use whichever library solves this problem. I looked at event bubbling like in this d3 example, but that only works for elements that are nested in the DOM. I have lots of independent elements that may overlap with lots of other elements and can therefore not structure my DOM that way.

我猜想,最后的方法是找到当前鼠标位置的元素,然后手动触发事件.因此,我查看了 document.elementFromPoint() ,但这只会产生1个元素(可能在SVG中不起作用?).我发现 jQuerypp 函数此处 >.该示例看起来不错,除了它是DIV而不是在SVG内部.用svg矩形元素替换div时,小提琴似乎 break .

I'm guessing the last resort is to find the elements that are at the current mouse position, and manually firing the events. Therefore, I looked at document.elementFromPoint(), but that would only yield 1 element (and may not work in SVG?). I found the jQuerypp function within, that finds the elements at a given position, see here. That example looks great, except it's DIVs and not inside SVG. When replacing divs with svg rectangle elements, the fiddle seems to break.

我该怎么办?!

推荐答案

在这里,很棒的评论给了我答案:可以通过使用

The great comments here gave me the answer: It's possible to propagate the event to underlying elements manually by finding them using getIntersectionList() at the cursor positon.

$('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/.

If the other listeners need the original event object, check out http://jsfiddle.net/michaschwab/w0wufbtn/13/.

非常感谢!

这篇关于在多个重叠的SVG元素上检测鼠标事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆