mousedown. propagation on siblings event.targets
Asked Answered
W

4

9

image

I have 2 sibling-nodes with 'position absolute' which both handle mousedown event. How can I trigger the handler of 'div 1' when I am clicking on the transparent area of the 'div 2' (on the pic.)

Wakeful answered 18/10, 2011 at 17:10 Comment(0)
T
4

If the overlapping elements are dynamic, I don't believe it is possible to accomplish this using regular event bubbling since the two overlapping elements in question are "siblings".

I had the same problem and I was able to solve it with more of a hitTest scenerio where I test if the user's mouse position is within the same area.

function _isMouseOverMe(obj){
    var t = obj.offset().top;
    var o = obj.offset().left;
    var w = obj.width();
    var h = obj.height();
    if (e.pageX >= o+1 && e.pageX <= o+w){
        if (e.pageY >= t+1 && e.pageY <= t+h){
            return true;
        }
    }
    return false
}
Thoron answered 1/3, 2012 at 2:49 Comment(0)
P
1

What you were looking was CSS's pointer-events property. I didn't make a research to learn whether it was available at the times the question been asked, but that I faced the same thing I'm taking a liberty of covering it.

Here're your two DIVs:

<body>
    <div class="inner div-1"></div>
        
    <div class="inner div-2">
        <div class="div-2__content-area"></div>
    </div>
</body>

Styling:

.inner {
  height: 10em;
  position: absolute;
  width: 15em;
}
.div-1 {
  /* Intrinsic styling & initial positioning, can be arbitrary */

  background: #ff0;
  left: 50%;
  top: 50%;
  transform: translate(-75%, -75%);
}
.div-2 {
  /* Intrinsic styling & initial positioning, can be arbitrary */

  background: rgba(0, 255, 0, 0.25);
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);

  /* Centering content area */

  align-items: center;
  display: flex;
  justify-content: center;

  /* Key feature -- making visible part of transparent DIV insensitive to mouse (pointer) events), letting them fire on the underlying element */

  pointer-events: none;
}
.div-2__content-area {
  /* Styling content area */

  background: #f00;
  height: 75%;
  width: 75%;

  /* Reverting 'pointer-events' perception to regular */

  pointer-events: auto;
}

Event listeners and displaying:

document.querySelector(".div-1").addEventListener("mousedown", (_) => {
    alert("div 1");
});
document.querySelector(".div-2__content-area").addEventListener("mousedown", (_) => {
    alert("Content area");
});

This all on codepen:

https://codepen.io/Caaat1/pen/RwZEJVP

Prolusion answered 17/11, 2021 at 12:31 Comment(0)
N
0

You'll want to use 3 event handlers, one for div1, one for div2, and one for contentArea. The contentArea handler should stop propagation so that the div2 handler is not called. The div2 handler should call the div1 handler:

function div1Click (e)
{
    // do something
}
function div2Click (e)
{
    div1Click.call(div1, e);
}
function contentAreaClick (e)
{
    e = e || window.event;
    if (e.stopPropagation) e.stopPropagation();
    e.cancelBubble = true;
    // do something
}
div1.onclick = div1Click;
div2.onclick = div2Click;
contentArea.onclick = contentAreaClick;
Numerous answered 18/10, 2011 at 17:34 Comment(1)
The problem is, in my case, that I have many such divs and they are dynamic (draggable) and div1 has the same structure, so I can't handle events this wayWakeful
B
0

Solution: Add css property pointer-events:none; to all the div, sibling-nodes or overlapping elements.

Now add the css property pointer-events:all; to all the clickable elements.

This will resolved the issue.

Basswood answered 17/8, 2023 at 9:2 Comment(1)
pointer-events: all is for SVG only.Alcides

© 2022 - 2024 — McMap. All rights reserved.