如何根据点击位置找到嵌套和转换的SVG元素(例如圆/路径/ ...)

时间:2017-05-30 12:24:05

标签: javascript svg onclick pointer-events

我是网络开发的初学者svg相关主题。

我认为这对你的svg专家来说应该很容易,但我现在正在努力解决这个问题。我在这个主题上找到的所有资源似乎都不适用于我相当简单的目标。

我的应用应该在Chrome浏览器中运行。

这样的DOM结构:

<div>
    <svg>
        <g>
            <circle></circle>
        </g>
    <svg>
</div>

虽然可能有更多的svg标签或嵌套的svg元素,但这是一般设置。

目标:

我想点击某处,找到位于我点击位置的svg子元素(例如圆圈)。我想到的基本功能是:

document.elementFromPoint(x, y)

问题:

1)所有元素都可以进行转换,例如应用于它们的平移,缩放和旋转,这会使事情变得复杂。

2)我只希望能够点击svg节点的子元素。

我的一些尝试:

https://jsfiddle.net/a6uLn9cn/3/

我试图在DIV和/或SVG节点上放置“pointer-events:none”。这样,我就可以避免这些是“可点击的”。这里有两个问题:我需要SVG节点上的指针事件,因为它需要进行缩放和放大。平移,以及例如点击事件不知何故,圈子“气泡”到DIV之后。

确保只有svg节点的子节点是“可单击的”的另一种方法是检查找到的元素的element.ownerSVGDocument。如果它为null或未定义,我知道找到的元素不是svg子元素。

为了解决实际点击已经转换的元素(通过它自己或通过其父元素)的问题,我尝试使用element.getBoundingClientRect(),它给出了元素的周围矩形。有了这个,我做了一个函数来确定点击是否在矩形元素周围:

e是click事件,elem是document.elementFromPoint()

收到的找到的元素
function clickIsInside(e, elem){
    var clickX = e.clientX;
    var clickY = e.clientY;

    var boxLeft = elem.getBoundingClientRect().left;
    var boxRight = elem.getBoundingClientRect().right;
    var boxTop = elem.getBoundingClientRect().top;
    var boxBottom = elem.getBoundingClientRect().bottom;

    if(clickX >= boxLeft && clickX <= boxRight && clickY >= boxTop && clickY <= boxBottom){
        return true;
    } else {
        return false;
    }
}

但是在我的jsfiddle中,你将无法在其boundingClientRect的最右侧“点击”路径,如果你想象boundingClientRect的位置,这对我没有意义。

此外,如果我在添加圈子后添加DOM的路径,我将无法再点击圈子,只能点击路径。我完全理解为什么,但是如果我需要点击它们呢?

我不确定我是否能够在这里解决我的烦恼,但我会非常感谢你们可能给我的任何意见。非常感谢你。

1 个答案:

答案 0 :(得分:1)

我发现我在问题中所做的大多数事情都只是让事情复杂化。解决方案只是检查找到的元素是否具有任何ownerSVGDElement,如果没有,则不调度click事件。对元素进行应用转换似乎没有任何问题,因为document.elementFromPoint()足够强大,可以找到转换后的元素。这个问题现在似乎没用了,所以我回答了&amp;关闭它仅仅是因为任何人都会遇到的罕见情况,或者像我一样尝试无脑的事情。

编辑:似乎我只能在2天内接受这个答案。