Detecting Mouse Events on Multiple Overlapping SVG Elements

丶灬走出姿态 提交于 2019-12-18 13:30:01

问题


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

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

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.

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.

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.

What do I do?!


回答1:


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

Working example: http://jsfiddle.net/michaschwab/w0wufbtn/6/

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

Thanks a lot!!



来源:https://stackoverflow.com/questions/29377443/detecting-mouse-events-on-multiple-overlapping-svg-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!