我创建了一个DOM元素,当它触发鼠标悬停事件时,它会创建新的DOM元素,例如标签或工具提示。不幸的是,有时这些元素是在鼠标当前位置的下方创建的。这将导致触发该DOM元素的mouseleave事件,该事件通常负责删除新创建的DOM元素。
换句话说,创建新元素时,鼠标不再“悬停”在最初触发事件的DOM元素上,而是“悬停”在新DOM元素上。浏览器将其读取为“ mouseleave”事件,然后触发“ mouseleave”功能。即使用户尚未移动鼠标,此事件也会发生,然后删除新元素。
这会导致出现一个循环,在该循环中迅速创建和删除新元素,并在将DOM元素的特定部分悬停在上方时引起闪烁效果。这是问题的简化版本:
https://jsfiddle.net/KingOfCramers/8wbfjap4/2/
var svg = d3.select("svg").style("background-color","grey")
var data = ["This is a circle"]
var circle = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx",100)
.attr("cy",100)
.attr("r", 20)
.style("fill","red")
circle
.on("mouseover",function(d){
var xPos = d3.select(this).attr("cx")
var yPos = d3.select(this).attr("cy")
svg
.append("text").text(d)
.attr("x",xPos)
.attr("y",yPos)
})
.on("mouseleave",function(){
d3.select("text").remove();
})
显然,此示例很愚蠢,但是在数据更加拥挤的情况下,仅将标签上下移动10或15像素是不切实际的解决方案。我也不能只创建相对于鼠标光标的标签,因为我经常会使用D3数据一次为多个DOM元素创建多个标签。大多数人会做什么来解决这个问题?
谢谢。
如果您不需要与该新元素进行交互,只需使用pointer-events: none;
:
.attr("pointer-events", "none")
这是您所做的更改的代码:
var svg = d3.select("svg").style("background-color", "grey")
var data = ["This is a circle"]
var circle = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 20)
.style("fill", "red")
circle
.on("mouseover", function(d) {
var xPos = d3.select(this).attr("cx")
var yPos = d3.select(this).attr("cy")
svg
.append("text").text(d)
.attr("x", xPos)
.attr("y", yPos)
.attr("pointer-events", "none")
})
.on("mouseleave", function() {
d3.select("text").remove();
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width=500 height=500></svg>
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句