捕获两个重叠元素上的鼠标悬停事件

巴拉德

因此,我有一个带有rect覆盖层的d3图表,用于保存mouseover事件中的十字线元素在覆盖层下,我还有其他rect显示数据,这些数据也具有mouseover事件处理程序,但是覆盖层阻止mouseover了以下子区域上触发器触发的事件。

let chartWindow = svg
  .append("g");

/* this holds axis groups, and cadlestick group*/
let candleStickWindow = chartWindow.append("g")
  //this event never fires
  .on('mousemove', ()=>console.log('mouse move'));

let candlesCrosshairWindow = chartWindow
  .append("rect")
  .attr("class", "overlay")

  .attr("height", innerHeight)
  .attr("width", innerWidth)
  .on("mouseover", function() {
    crosshair.style("display", null);
  })
  .on("mouseout", function() {
    crosshair.style("display", "none");
    removeAllAxisAnnotations();
  })
  .on("mousemove", mousemove);

CrosshairWindow具有CSS属性pointer-events: all如果我删除了该事件,则会在上触发事件,candleStickWindow但不会触发CrosshairWindow如何使鼠标事件同时出现在这两个元素上?

谢谢你的帮助!

更新我将十字准线rect元素更改为在底部,这有点奏效,烛台条mouseover事件有效,但它阻止了十字准线起作用。

在此处输入图片说明

altocumulus

One solution that comes to mind might use event bubbling which, however, only works if the events can bubble up along the same DOM sub-tree. If, in your DOM structure, the crosshairs rectangle and the other elements do not share a common ancestor to which you could reasonably attach such listener, you need to either rethink your DOM or resort to some other solution. For this answer I will lay out an alternative approach which is more generally applicable.

You can position your full-size rect at the very bottom of your SVG and have its pointer-events set to all. That way you can easily attach a mousemove handler to it to control your crosshairs' movements spanning the entire viewport. As you have noticed yourself, however, this does not work if there are elements above which have listeners for that particular event type attached to them. Because in that case, once the event has reached its target, there is no way propagating it further to the underlying rectangle for handling the crosshairs component. The work-around is easy, though, since you can clone the event and dispatch that new one directly to your rectangle.

Cloning the event is done by using the MouseEvent() constructor passing in the event's details from the d3.event reference:

new MouseEvent(d3.event.type, d3.event)

然后,您可以rect使用.dispatchEvent()以下EventTarget接口实现方法将新创建的事件对象分派到crosshairs元素SVGRectElement

.dispatchEvent(new MouseEvent(d3.event.type, d3.event));

由于您的问题中没有完整的示例,因此我自己创建了一个工作示例来演示该方法。您可以拖动蓝色圆圈,它是十字准线组件的简化版本。请注意,即使在橙色矩形下方,圆也可以无缝移动。为了演示附加在这些小矩形上的事件处理程序,当使用鼠标指针进入或离开它们时,它们将转换为绿色,然后转换为橙色。

const width = 500;
const height = 500;
const radius = 10;
const orange = d3.hsl("orange");
const steelblue = d3.hsl("steelblue");
const limegreen = d3.hsl("limegreen");

const svg = d3.select("body")
  .append("svg")
    .attr("width", width)
    .attr("height", height);
    
const target = svg.append("rect")
    .attr("x", 0)
    .attr("y", 0)
    .attr("width", width)
    .attr("height", height)
    .attr("fill", "none")
    .attr("pointer-events", "all")
    .on("mousemove", () => {
      circle.attr("cx", d3.event.clientX - radius);
      circle.attr("cy", d3.event.clientY - radius);
    });

const circle = svg.append("circle")
    .attr("r", radius)
    .attr("fill", steelblue)
    .attr("pointer-events", "none");
    
const rect = svg.selectAll(null)
  .data(d3.range(3).map(d => [Math.random() * width, Math.random() * height]))
  .enter().append("rect")
    .attr("x", d => d[0])
    .attr("y", d => d[1])
    .attr("width", 50)
    .attr("height", 50)
    .attr("fill", orange)
    .attr("opacity", 0.5)
    .on("mouseover", function() { 
      d3.select(this).transition().attr("fill", limegreen);
    })
    .on("mousemove", function() { 
      target.node().dispatchEvent(new MouseEvent(d3.event.type, d3.event));
    })
    .on("mouseout", function() { 
      d3.select(this).transition().attr("fill", orange);
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

鼠标悬停在两个元素之间的问题

来自分类Dev

将鼠标悬停在同一位置的两个元素上

来自分类Dev

如何只允许鼠标悬停在两个元素上?

来自分类Dev

当鼠标悬停在两个重叠的画布上时,CSS下拉菜单不起作用

来自分类Dev

将鼠标悬停在两个元素上可将效果设置为一个元素

来自分类Dev

如果悬停在另一个重叠元素上,请保持鼠标悬停

来自分类Dev

处理两个重叠节点上的鼠标事件-Javafx

来自分类Dev

处理两个重叠节点上的鼠标事件-Javafx

来自分类Dev

d3.js同时在两个图表上进行鼠标悬停事件

来自分类Dev

同时触发两个按钮的Silverlight按钮鼠标悬停事件

来自分类Dev

鼠标悬停两个元素1秒后如何关闭下拉菜单?

来自分类Dev

在<datalist>上注册一个鼠标悬停事件

来自分类Dev

希望将鼠标悬停在容器上,并使两个元素(一个Image)和p同时反应并更改

来自分类Dev

每个元素多个鼠标悬停事件

来自分类Dev

WPF如何引发两个相互重叠的UIElement上的鼠标事件

来自分类Dev

如何将鼠标悬停在一个 div 上以触发两个不同 div 的更改?

来自分类Dev

JSTree上的鼠标悬停事件

来自分类Dev

如何将鼠标悬停在两个不同表的同一行上?

来自分类Dev

鼠标悬停事件

来自分类Dev

将鼠标悬停在元素上?

来自分类Dev

如何固定位置元素,以便将鼠标悬停在一个元素上时,其他两个元素应保留在同一位置

来自分类Dev

如何固定位置元素,以便将鼠标悬停在一个元素上时,其他两个元素应保留在同一位置

来自分类Dev

如何获得两个图像以在鼠标悬停/鼠标移开时切换?

来自分类Dev

鼠标悬停。保持课堂直到将鼠标悬停在另一个元素上

来自分类Dev

彼此重叠的两个元素上的jQuery.bind上下文菜单事件

来自分类Dev

检测鼠标悬停在重叠的+透明图像上

来自分类Dev

在4个按钮之间移动,并在两个按钮之间单击鼠标悬停

来自分类Dev

将鼠标悬停在具有较高z-index的元素上的事件?

来自分类Dev

如何在堆叠的SVG元素上触发鼠标悬停事件

Related 相关文章

  1. 1

    鼠标悬停在两个元素之间的问题

  2. 2

    将鼠标悬停在同一位置的两个元素上

  3. 3

    如何只允许鼠标悬停在两个元素上?

  4. 4

    当鼠标悬停在两个重叠的画布上时,CSS下拉菜单不起作用

  5. 5

    将鼠标悬停在两个元素上可将效果设置为一个元素

  6. 6

    如果悬停在另一个重叠元素上,请保持鼠标悬停

  7. 7

    处理两个重叠节点上的鼠标事件-Javafx

  8. 8

    处理两个重叠节点上的鼠标事件-Javafx

  9. 9

    d3.js同时在两个图表上进行鼠标悬停事件

  10. 10

    同时触发两个按钮的Silverlight按钮鼠标悬停事件

  11. 11

    鼠标悬停两个元素1秒后如何关闭下拉菜单?

  12. 12

    在<datalist>上注册一个鼠标悬停事件

  13. 13

    希望将鼠标悬停在容器上,并使两个元素(一个Image)和p同时反应并更改

  14. 14

    每个元素多个鼠标悬停事件

  15. 15

    WPF如何引发两个相互重叠的UIElement上的鼠标事件

  16. 16

    如何将鼠标悬停在一个 div 上以触发两个不同 div 的更改?

  17. 17

    JSTree上的鼠标悬停事件

  18. 18

    如何将鼠标悬停在两个不同表的同一行上?

  19. 19

    鼠标悬停事件

  20. 20

    将鼠标悬停在元素上?

  21. 21

    如何固定位置元素,以便将鼠标悬停在一个元素上时,其他两个元素应保留在同一位置

  22. 22

    如何固定位置元素,以便将鼠标悬停在一个元素上时,其他两个元素应保留在同一位置

  23. 23

    如何获得两个图像以在鼠标悬停/鼠标移开时切换?

  24. 24

    鼠标悬停。保持课堂直到将鼠标悬停在另一个元素上

  25. 25

    彼此重叠的两个元素上的jQuery.bind上下文菜单事件

  26. 26

    检测鼠标悬停在重叠的+透明图像上

  27. 27

    在4个按钮之间移动,并在两个按钮之间单击鼠标悬停

  28. 28

    将鼠标悬停在具有较高z-index的元素上的事件?

  29. 29

    如何在堆叠的SVG元素上触发鼠标悬停事件

热门标签

归档