我有一个带有各种路径的 SVG 文件,它使用 object
标签嵌入到 HTML 页面中。 Javascript 用于为每个路径提供一些交互性 - 单击它时,将显示工具提示 rect
。这是它的样子:
我希望当有人在工具提示关联的路径之外单击时工具提示消失,这是通过向每个路径添加这样的事件监听器来实现的:
path.addEventListener("click", function(event){
if (!isTipShown()){
createTooltip()
}
else{
hideTooltip()
}
})
isTipShown
、createTooltip
和 hideTooltip
是检查 SVG DOM 并相应修改它的函数。
这行得通,但如果点击进入路径之间的空白区域,它就会失败 - 因为没有对象可以捕捉到它。
可以选择什么方法来实现这样的功能?
我目前的想法:
- 创建一个覆盖整个视口(viewport)的透明矩形,并将其用作点击目标。如何确保矩形到达所有内容的底部?
- 整个 HTML 文档的点击处理程序可以解决问题,但前提是用户在视口(viewport)本身之外点击。
最佳答案
解决方案是确保矩形位于路径下方,就好像它是底层一样。
SVG does not have a concept of layers , 但可以通过确保 rect
在 SVG DOM 中的所有元素之前来实现,并且所有后续元素都将放置在它之上,视觉上:
<rect x="0" y="0" width="30" height="30" fill="purple"/>
<rect x="20" y="5" width="30" height="30" fill="blue"/>
<rect x="40" y="10" width="30" height="30" fill="green"/>
<rect x="60" y="15" width="30" height="30" fill="yellow"/>
<rect x="80" y="20" width="30" height="30" fill="red"/>
这是在实践中如何完成的(svgDoc
变量是根 SVG 元素):
function createBackgroundRectangle(svgDoc){
var rect = svgDoc.createElementNS("http://www.w3.org/2000/svg", 'rect')
rect.setAttributeNS(null, 'height', 500)
rect.setAttributeNS(null, 'width', 900)
rect.setAttributeNS(null, 'id', 'pseudo-background')
rect.setAttributeNS(null, 'x', 0)
rect.setAttributeNS(null, 'y', 0)
// the opacity is set to 0, so it doesn't get in the way visually. For debugging
// purposes, you can change it to another value and see the actual rectangle
rect.setAttributeNS(null, 'style', 'opacity:0;fill:#ffd42a;fill-opacity:1;')
svgDoc.rootElement.insertBefore(rect, svgDoc.rootElement.children[0])
}
svgDoc.rootElement.insertBefore(rect, svgDoc.rootElement.children[0])
使其成为第一个,因为它被插入到索引 0 处的当前子元素之前。
关于javascript - 如何捕获点击 View 框的 SVG 单击事件,而不是它上面的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56270718/