最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to trigger click of both elements, when clicking overlapping area - Stack Overflow

programmeradmin1浏览0评论

I have two elements overlapping each other, Both has click events. Clicking on each element works fine.

If I click on an overlapping area as shown below, can I trigger the click of both?

Below is my code

$("#circle1").click(function(d) {
  alert("circle1");
});
$("#circle2").click(function(d) {
  alert("circle2");
});
.path {
  fill: red;
}
<script src=".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>

I have two elements overlapping each other, Both has click events. Clicking on each element works fine.

If I click on an overlapping area as shown below, can I trigger the click of both?

Below is my code

$("#circle1").click(function(d) {
  alert("circle1");
});
$("#circle2").click(function(d) {
  alert("circle2");
});
.path {
  fill: red;
}
<script src="https://cdnjs.cloudflare./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>

Share Improve this question edited Jan 14, 2020 at 9:54 Reza Paidar 8835 gold badges21 silver badges52 bronze badges asked Dec 19, 2019 at 8:27 ozilozil 7,1459 gold badges36 silver badges61 bronze badges 1
  • If you have some way of determining that click was on the mon area you can simply call $( "#circle2" ).trigger( "click" ); This is not the right way, but just an idea on the top of my head – M Usama Alvi Commented Dec 19, 2019 at 8:29
Add a ment  | 

3 Answers 3

Reset to default 4

I would use clip-path to get the intersection of the 2 circles. Then I would attach the event to intersection.

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>

You should not rely on any approach that calculates the position of the intersection or that creates another element just to pute the intersection. Such approaches will eventually fail or simply bee too plicated and cumbersome.

Instead of that, use the event itself and a method like document.elementFromPoint to get all elements under the click. For instance, you can use document.elementFromPoint “recursively”, as described here. Then, using selection.dispatch, you dispatch the click event to all elements under the click.

Here is a very basic demo (click on the blue circle, the red circle or the intersection):

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/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>

Here is how you can calculate the overlap area calculate clientX for each click event and make sure it is overlap area as you have already provide X and Y for your circles. Here is example. In example, I have provided a rough idea you can calculate according to your actual dimesions.

$(".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./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>

发布评论

评论列表(0)

  1. 暂无评论