[英]document.elementFromPoint returning different elements for same input
我正在使用document.elementFromPoint
来确定某个点的 svg 形状是什么。 当我注意到我为相同的输入获得不同的输出时,我正在此图像上尝试elementFromPoint
。
这正是我为重现性所做的。
body{margin:0;}
。elementFromPoint
。 大多在.25,50,但有时只是稍微向右或向左一点。 有时用同一个 arguments 一遍又一遍地调用,看看它是否会改变。我的问题是为什么会发生这种情况? 它有规律吗? 有没有办法防止它? 谢谢。
虽然我不能告诉你为什么会发生这种情况,或者如何防止这种情况发生,但“模式”,或者让我们更好地说,可以缩小不一致行为的原因。
让我们看看调用elementFromPoint
返回的路径。 其中有两个,如果省略 id 和类,即使考虑到它们的父元素,它们看起来也一样:
<g transform="translate(-1.775,-1.575)">
<path d="M 1.9,551.3 V 1.7 H 1102 V 551.3 H 2.3" />
</g>
如果您重写路径以解决transform
,您将在(浏览器)视口坐标中获得路径 - 为清楚起见,我已将V
和H
命令重写为L
:
<path d="M 0.125,549.725 L 0.125,0.125 L 1100.125,0.125 L 1100.125,549.725 L 0.525,549.725" />
SVG 包含描述这些元素的填充和描边的样式表。 这是相关的摘录:
.seabase {
fill: #C6ECFF;
stroke: none;
}
.mapborder {
fill: none;
stroke: #0978AB;
}
path, circle {
stroke-width: 0.25;
}
那么应该从document.elementFromPoint(0.25,50)
返回什么? 在给定坐标处找到的最顶层元素,前提是pointer-events
属性允许该元素成为命中测试的目标。
没有为元素显式设置pointer-events
,因此应用了visiblePainted
的默认值。 这意味着(至少部分)不透明的填充或描边都可以被击中。
两个候选的底部元素<path class="seabase"/>
有一个可见的填充,但没有边框。 点(0.25,50)
在该填充内。
两个候选元素的最顶部元素<path class="mapborder"/>
没有填充,但有一个宽度为 0.25 的可见边框,一半向内延伸,另一半向路径轮廓外侧延伸。 在左侧,有一个垂直子路径M 0.125,549.725 L 0.125,0.125
。 不涉及角落的细节,笔画可以等效地绘制为具有定义的填充路径
M 0,549.725 L 0,0.125 L 0.25,0.125 L 0.25,549.725 Z
换句话说,点(0.25,50)
正好在笔画的轮廓上。 规范对后果非常清楚:
形状的零宽度几何轮廓包含在要绘制的区域中。
该点应该击中mapborder
元素,因为该点是其可见的绘制描边的一部分。 如果,如您所描述的,浏览器有时会返回seabase
元素,那是错误的。
我可以打开 go 并推测这种行为的原因,但我认为这没有实际意义。
你能阻止它吗? 仅当您能够始终避免所有路径的确切轮廓,或者如果它们具有笔划,则该笔划的轮廓。 这几乎不切实际,因为您必须找出浏览器是否错过了它应该点击的东西,而您不知道错过了什么。
最后,还有第二个界面可以使用。 它是 SVG 规范的一部分,而elementFromPoint
是 CSSOM 规范的一部分。 这是否会对浏览器的实现产生影响,我不能说。
document.querySelector('.seabase').isPointInFill(new DOMPoint(2.025,48.425));
document.querySelector('.mapborder').isPointInStroke(new DOMPoint(2.025,48.425));
请注意,您需要提供一个要测试的元素,您无法获得哪个元素位于顶部的信息,并且坐标在本地用户空间中表示(在应用transform
之前)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.