Javascript svg元素能否触发自身下svg元素的点击事件?
这里没有问题 我想知道如果它们覆盖了鼠标坐标,是否可能触发它下面的元素(路径、圆等)的“点击”事件? 最好使用typescript和d3.js库Javascript svg元素能否触发自身下svg元素的点击事件?,javascript,typescript,d3.js,Javascript,Typescript,D3.js,这里没有问题 我想知道如果它们覆盖了鼠标坐标,是否可能触发它下面的元素(路径、圆等)的“点击”事件? 最好使用typescript和d3.js库 作为一个例子,考虑有两个圆圈(一个小的在Z位置大一个),这两个都在点击时显示一个消息。 我想,如果我在小圆圈内单击,它的消息会出现,然后大圆圈的消息也会出现 下面是我的示例的HTML代码[编辑:D3的更改版本]: <!DOCTYPE html> <style> circle { fill: lightgreen; strok
作为一个例子,考虑有两个圆圈(一个小的在Z位置大一个),这两个都在点击时显示一个消息。 我想,如果我在小圆圈内单击,它的消息会出现,然后大圆圈的消息也会出现
下面是我的示例的HTML代码[编辑:D3的更改版本]:<!DOCTYPE html>
<style>
circle { fill: lightgreen; stroke: #000; }
</style>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
使用此代码,单击大圆圈显示外部和SVG消息。点击小圆圈显示内部和SVG消息,但我希望序列为内部、外部和SVG
[编辑:纠正“传播”一词的误用]
我将元素的“指针事件”属性设置为“全部”。
我知道这使它们“无法通过”,但我希望能够触发它们的事件,也能触发它们下面元素的事件
或者,有没有什么好方法可以获得一个svg元素列表,这些元素覆盖给定的坐标[X,Y](可以通过d3.鼠标
获得),这样就可以手动触发它们各自的单击事件
感谢您的帮助。解决方案将取决于控制svg元素大小的形状类型和参数。如果需要非最佳但通用的解决方案,可以使用图元的边界框。使用边界框,您可以通过针对[x,y]目标测试x和y范围来确定是否有任何对象位于[x,y]上方 您可以优化以下代码并将其插入任何d3功能块:
((形状)=>{
设bbox=this.getBBox();
设minX=bbox.x;
设maxX=minX+bbox.width;
设minY=bbox.y;
设maxY=minY+bbox.width;
设isOver=shape.x>minX&&shape.xminY&&shape.y
解决方案将取决于形状类型和控制svg元素大小的参数。如果需要非最佳但通用的解决方案,可以使用图元的边界框。使用边界框,您可以通过针对[x,y]目标测试x和y范围来确定是否有任何对象位于[x,y]上方 您可以优化以下代码并将其插入任何d3功能块:
((形状)=>{
设bbox=this.getBBox();
设minX=bbox.x;
设maxX=minX+bbox.width;
设minY=bbox.y;
设maxY=minY+bbox.width;
设isOver=shape.x>minX&&shape.xminY&&shape.y
首先,此解决方案使用的是D3V5,而不是您在HTML中引用的D3V2(已经9年了) 回到你的问题,你说: 我希望能够触发它们的事件并传播到它们下面的元素,直到SVG本身被触发 这不是传播的意思。冒泡表示在DOM树中向上,但这些圆不是父/子,它们只是兄弟。因此,您想要的与传播无关,因此我们需要一种不同的方法 我在这里建议的方法使用
elementFromPoint
,以获取您单击的坐标下的所有元素,并结合d3.dispatch
来调度单击(我找到了getAllegements
函数,并对其进行了修改,以便与d3一起使用)。最后,我需要点击标记,因为elementFromPoint
会忽略指针事件设置为none
的元素(顺便说一下,它是指针事件
,而不是指针事件
)
以下是演示:
let clicked;
var svg=d3.选择(“正文”).追加(“svg”)
.style(“浮动”、“左”)
.attr(“宽度”,480)
.attr(“高度”,480)
.attr('pointer-event','all');
svg.append(“圆”)
.attr('pointer-event','all')
.attr(“cx”,240)
.attr(“cy”,240)
.attr(“r”,200)
.on(“单击”,函数(){
如果(!单击)返回;
日志(“外部”)
});
svg.append(“圆”)
.attr('pointer-event','all')
.attr(“cx”,240)
.attr(“cy”,240)
.attr(“r”,100)
.on(“单击”,函数(){
如果(!单击)返回;
日志(“内部”)
});
var div=d3.选择(“主体”).追加(“div”)
.样式(“浮动”、“左”);
功能日志(消息){
附加部分(“p”)
.文本(信息)
.style(“背景”,“#ff0”)
.transition()
.持续时间(2500)
.样式(“不透明度”,1e-6)
.remove();
}
d3.选择(“svg”)。单击(“单击”,函数(){
单击=真;
获取等位基因(…d3.mouse(this));
日志(“SVG”)
单击=假;
函数(x,y){
常量元素=[];
让thisElement=document.elementFromPoint(x,y);
while(thisElement&&thisElement.nearestViewportElement){
元素。推(this元素);
d3.选择(此元素)。样式(“显示”、“无”);
thisElement=document.elementFromPoint(x,y);
}
元素。forEach(函数(elm){
d3.选择(elm).style(“显示”,null)
.发送(“点击”);
});
};
})
圈{
填充物:浅绿色;
行程:#000;
}
首先,此解决方案使用的是D3 v5,而不是您在HTML中引用的D3 v2(已经9年了)
回到你的问题,你说:
我希望能够触发它们的事件并传播到它们下面的元素,直到SVG本身被触发
这不是传播的意思。冒泡表示在DOM树中向上,但这些圆不是父/子,它们只是兄弟。因此,您想要的与传播无关,因此我们需要一种不同的方法
我的建议
var svg = d3.select("body").append("svg")
.style("float", "left")
.attr("width", 480)
.attr("height", 480)
.attr('pointer-events', 'all')
.on("click", log("SVG"));
svg.append("circle")
.attr('pointer-events', 'all')
.attr("cx", 240)
.attr("cy", 240)
.attr("r", 200)
.on("click", log("OUTER"));
svg.append("circle")
.attr('pointer-event', 'all')
.attr("cx", 240)
.attr("cy", 240)
.attr("r", 100)
.on("click", log("INNER"));
var div = d3.select("body").append("div")
.style("float", "left");
function log(message) {
return function() {
div.append("p")
.text(message)
.style("background", "#ff0")
.transition()
.duration(2500)
.style("opacity", 1e-6)
.remove();
};
}
<d3 function block>((shape)=>{
let bbox = this.getBBox();
let minX=bbox.x;
let maxX=minX+bbox.width;
let minY=bbox.y;
let maxY=minY+bbox.width;
let isOver=shape.x>minX && shape.x < maxX && shape.y > minY && shape.y < maxY;
//..do something depending on the value of isOver
})