我创建了一个DOM元素,当它触发鼠标悬停事件时,会创建新的DOM元素,例如标签或工具提示。不幸的是,有时这些元素是在鼠标的当前位置下创建的。这会导致触发该DOM元素的mouseleave事件,这通常负责删除新创建的DOM元素。
换句话说,当创建新元素时,鼠标不再是" hovering"最初触发事件的DOM元素,但 new 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元素。大多数人为解决这个问题做了什么?
感谢。
答案 0 :(得分:1)
如果您不需要与该新元素进行互动,请使用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>
&#13;