我尝试使用 D3 在现有的点击事件监听器中添加第二个点击事件监听器,但没有成功。
基本上,我有一张事件 map (圆圈)。我希望用户能够点击一个圆圈并出现一个弹出窗口。我希望该弹出窗口仅在用户第二次单击任何地方时消失。因此,单击一个圆圈将实例化弹出窗口并绑定(bind)它,第二次单击“任何地方”将使弹出窗口消失并将圆圈恢复为仅响应悬停,除非再次单击。
我通过在 circle 事件监听器中添加另一个“body”点击事件监听器来解决这个问题:
// event listener: if events (circles) are clicked, instantiate pop-up
d3.selectAll(".events").on("click", function(d) {
console.log("event clicked!")
//disable hover event listeners
d3.selectAll(".events").on("mouseout", null);
d3.selectAll(".events").on("mouseover", null);
popup.transition()
.duration(200)
.style("opacity", .9);
popup.html(d.ArtistBio)
// if user clicks a SECOND time, anywhere, make popup disappear
d3.select("body").on("click", function(d) {
console.log("body clicked")
//hide popup
popup.transition()
.duration(200)
.style("opacity", 0);
//revert back to hover, unless user clicks again!
d3.selectAll(".events").on("mouseout", true);
d3.selectAll(".events").on("mouseover", true);
d3.selectAll(".events").on("mouseout", function(d) {
console.log("mousing out!")
popup.transition()
.duration(200)
.style("opacity", 0);
})
// mouseover event listers added back in
d3.selectAll(".events").on("mouseover", function(d) {
popup.transition()
.duration(200)
.style("opacity", .9);
popup.html(d.ArtistBio)
})
})
我的问题是这两个事件是同时触发的,而不是按顺序触发的:一旦我点击一个圆圈事件, body 点击事件监听器也被实例化,所以弹出窗口一呈现就被删除.有没有办法以类似于我上面描述的方式来做我想做的事情?提前致谢。
最佳答案
点击会冒泡,这是正常预期的。为避免这种情况,请使用 event.stopPropagation
。您还可以使用 d3.events
(当它们存在时...):
d3.event.stopPropagation();
这是演示,单击矩形并在其外部:
d3.select("rect").on("click", function() {
console.log("rectangle clicked");
d3.event.stopPropagation();
d3.select("body").on("click", function() {
console.log("body clicked")
})
})
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg>
<rect width="50" height="50" x="100" y="50"></rect>
</svg>
关于javascript - 在单击事件监听器中添加第二个单击事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58176565/