如何在单击重叠区域时触发两个元素的单击事件

5

我有两个元素重叠,它们都有点击事件。点击每个元素都可以正常工作。

如果我点击如下所示的重叠区域,是否可以同时触发两个元素的点击事件?
enter image description here

以下是我的代码

$("#circle1").click(function(d) {
  alert("circle1");
});
$("#circle2").click(function(d) {
  alert("circle2");
});
.path {
  fill: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg width="525" height="226">
   <circle id="circle1" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
   <circle id="circle2" cx="80" cy="50" r="40" stroke="black" stroke-width="3" fill="transparent" />
</svg>


如果您有某种确定点击是在公共区域的方法,您可以简单地调用 $( "#circle2" ).trigger( "click" );。这不是正确的方法,只是我脑海中的一个想法。 - M Usama Alvi
3个回答

4
我会使用 clip-path 来获取两个圆的交集。然后,我将把事件附加到交集上。

intersection.addEventListener("click",()=>{
  console.log("intersection")
})
circle{stroke-width:3;stroke:black;}
svg{border:1px solid}
<svg id="svg" viewBox="0 0 525 226">
  <defs>
   <circle id="circle1" cx="50" cy="50" r="40" />
   <circle id="circle2" cx="80" cy="50" r="40"  />
   <clipPath id="clip"><use xlink:href="#circle2"  />
</clipPath>  
  </defs>
  <use xlink:href="#circle1" class="circle"  fill="red" /> 
  <use xlink:href="#circle2" class="circle"  fill="transparent" />

  <use xlink:href="#circle1" id="intersection" clip-path="url(#clip)"  fill="gold" />
</svg>


1
漂亮的解决方案! - Alexandr_TT

4
您不应该依赖于计算交点位置或创建另一个元素来计算交点的任何方法。这样的方法最终会失败或变得过于复杂和繁琐。
相反,使用事件本身和像document.elementFromPoint这样的方法获取单击下的所有元素。例如,您可以像这里描述的那样“递归”使用document.elementFromPoint。然后,使用selection.dispatch,将单击事件分派到单击下的所有元素。
这是一个非常基本的演示(单击蓝色圆圈、红色圆圈或交点):

let clicked;
d3.select(".blue").on("click", function() {
  if (!clicked) return;
  console.log("blue circle were clicked")
});
d3.select(".red").on("click", function() {
  if (!clicked) return;
  console.log("red circle were clicked")
});
d3.select("svg").on("click", function() {
  clicked = true;
  getAllElements(...d3.mouse(this));
  clicked = false;

  function getAllElements(x, y) {
    const elements = [];
    let thisElement = document.elementFromPoint(x, y);
    while (thisElement && thisElement.nearestViewportElement) {
      elements.push(thisElement);
      d3.select(thisElement).style("display", "none");
      thisElement = document.elementFromPoint(x, y);
    }
    elements.forEach(function(elm) {
      d3.select(elm).style("display", null)
        .dispatch("click");
    });
  };
})
.as-console-wrapper {
  max-height: 30% !important;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg>
  <circle cx="100" cy="75" r="60" fill="powderblue" stroke="gray" stroke-width="2" opacity="0.75" class="blue"></circle>
  <circle cx="170" cy="75" r="60" fill="tomato" stroke="gray" stroke-width="2" opacity="0.75" class="red"></circle>
</svg>


2

以下是计算重叠区域的方法,您需要为每个“点击事件”计算clientX,并确保它与您已经为圆形提供的XY重叠。这里是一个例子。在示例中,我提供了一个大致的想法,您可以根据实际尺寸进行计算。

$(".circle").click(function(e) {
    if((event.clientX>50  && event.clientX<80) && (event.clientY>25 && event.clientY<85)){
    alert('overlaper area');
    }
});
.path {
  fill: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<svg width="525" height="226">
   <circle class="circle" id="circle1" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
   <circle class="circle" id="circle2" cx="80" cy="50" r="40" stroke="black" stroke-width="3" fill="transparent" />
</svg>


2
如果我没弄错的话,你的代码将覆盖一个矩形区域,而不是重叠的区域。 - Temani Afif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接