取消D3中新创建的DOM元素上的鼠标悬停

时间:2018-01-07 01:07:38

标签: javascript css dom d3.js mouseevent

我创建了一个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元素。大多数人为解决这个问题做了什么?

感谢。

1 个答案:

答案 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;
&#13;
&#13;