我是 Web 开发和 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/
我试图将“pointer-events:none”放在 DIV 和/或 SVG 节点上。这样,我就可以避免这些是“可点击的”。但是这里有两个问题:我需要 SVG 节点上的指针事件,因为它需要被缩放和平移,以及例如圆圈上的点击事件以某种方式“冒泡”到 DIV。
另一种确保 svg 节点的子节点是“可点击”的方法是检查 element.ownerSVGDocument 中找到的元素。如果它为 null 或未定义,我知道找到的元素不是 svg 子元素。
为了解决实际单击已转换的元素(通过其自身或通过其父元素)的问题,我尝试使用 element.getBoundingClientRect() ,它为我提供了元素的周围矩形。有了这个,我做了一个函数来确定点击是否在矩形周围的元素内:
e 是点击事件,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,我将无法再单击圆圈,而只能单击路径。我完全明白为什么,但如果我需要同时点击两者怎么办?
我不确定我是否能够在这里解决我的麻烦,但我会非常感谢你们可能给我的任何意见。非常感谢。