Javascript 如何捕获命中viewbox的SVG单击事件,而不是其上的元素?
我有一个具有各种路径的SVG文件,它使用Javascript 如何捕获命中viewbox的SVG单击事件,而不是其上的元素?,javascript,html,svg,Javascript,Html,Svg,我有一个具有各种路径的SVG文件,它使用object标记嵌入到HTML页面中。Javascript用于为每个路径提供一些交互性—单击该路径时,将显示工具提示rect。这就是它看起来的样子: 我希望当有人在工具提示关联的路径之外单击时,工具提示消失,这是通过向每个路径添加这样的事件侦听器来实现的: path.addEventListener("click", function(event){ if (!isTipShown()){ createTooltip()
object
标记嵌入到HTML页面中。Javascript用于为每个路径提供一些交互性—单击该路径时,将显示工具提示rect
。这就是它看起来的样子:
我希望当有人在工具提示关联的路径之外单击时,工具提示消失,这是通过向每个路径添加这样的事件侦听器来实现的:
path.addEventListener("click", function(event){
if (!isTipShown()){
createTooltip()
}
else{
hideTooltip()
}
})
isTipShown
、createTooltip
和hideTooltip
是检查SVG DOM并相应修改它的函数
这是可行的,但如果单击指向路径本身之间的空白区域,则会失败,因为没有对象可以捕捉它
可以选择什么方法来实现这些功能?
我现在的想法是:
- 创建一个覆盖整个视口的透明矩形,并将其用作单击目标。如何确保矩形位于所有内容的底部李>
- 整个HTML文档的单击处理程序会起作用,但仅当用户在视口之外单击时
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.rootElement.insertBefore(rect,svgDoc.rootElement.children[0])
使其成为第一个,因为它插入到索引0处的当前子级之前。形状上的工具提示不是我的SVG!
按下svg时如何最好地删除工具提示?他们认为我解决问题的方法是:
删除工具提示(而不是删除)可以在显示新路径时再次重用相同的工具提示 以下是一个例子:
document.addEventListener(“DOMContentLoaded”,function()){
var pathRed=document.getElementById(“红色”);
var pathrange=document.getElementById(“橙色”);
var pathBlue=document.getElementById(“蓝色”);
变量路径=[pathRed,PathRange,pathBlue];
var toolTip=document.createElement(“div”);
toolTip.id=“toolTip”;
var svg=document.getElementById(“框”);
显示的var=假;
path.forEach(函数(元素){
元素。addEventListener(“单击”),函数(事件){
如果(显示==错误){
toolTip.innerText=element.id;
toolTip.style.top=(event.pageY)+“px”;
toolTip.style.left=(event.pageX)+“px”;
document.body.appendChild(工具提示);
显示=正确;
//仅单击路径
event.stopPropagation();
}否则{
移除工具头();
}
});
});
addEventListener(“单击”),函数(事件){
移除工具头();
event.preventDefault();
});
函数removeToolTip(){
显示=假;
if(document.body.contains(工具提示)){
document.body.removeChild(工具提示);
}
}
});代码>
#工具提示{
位置:绝对位置;
背景色:#00000099;
填充:2px;
边界半径:2px;
颜色:白色;
字体大小:20px;
}
点击框!
您可以对文档使用单击处理程序并检查event.currentTarget,如果单击目标是路径,则不要执行任何操作,否则隐藏工具提示。我会执行rect操作。不确定你所说的“一切尽在最底层”是什么意思,你所描述的方法是有效的,但是当点击进入路径之间的空白处时它就会失败(因为没有元素接收到点击事件)。Robert,将其视为层-透明矩形放置在所有东西的顶部,因此所有单击都指向它(而不是它下面的路径)。你看不到它,因为它是透明的,但它仍然可以点击。
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])
}