Отмена наведения мыши на вновь созданных элементах DOM в D3

1

Я создал элемент DOM, который, когда он запускает событие mouseover, создает новые элементы DOM, такие как метки или всплывающие подсказки. К сожалению, иногда эти элементы создаются под текущей текущей позицией мыши. Это вызывает событие mouseleave этого элемента DOM, который часто отвечает за удаление вновь созданного элемента 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. Что делают большинство людей для решения этой проблемы?

Благодарю.

Теги:
d3.js
dom
mouseevent

1 ответ

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>
  • 1
    Вау, не знал, что ответ будет таким простым. Спасибо, Герардо, кажется, ты всегда отвечаешь на мои вопросы, хахаха.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню