Home > Blockchain >  How to forward specific event to overlapped DOM element
How to forward specific event to overlapped DOM element

Time:05-18

enter image description here

I have two completely overlapped divs; The top layer has a scroll behavior because it has overflowing content, and I want to keep the scrolling behavior.

The underlying layer has different section with different click handler; boxes (X, Y, Z) in the picture.

How do I have a click handler for the underlying layer while keeping the scrolling on the top layer?

I have tried CSS pointer-events: none; but it forwards all events, which cause the scrolling on the top layer to be disabled.

I have tried to manually dispatchEvent using javascript, but the event sourcing doesn't work as normal.

Here is the DOM structure

 <div>
    <div
      ref="layer2"
      
      style="width: 600px"
      @click="handleLayer2"
    >
      <div
        @click="handleSection('x')"
        
      >
        X
      </div>
      <div
        @click="handleSection('y')"
        
      >
        Y
      </div>
      <div
        @click="handleSection('z')"
        
      >
        Z
      </div>
    </div>

    <div
      
      style="width: 600px"
      @click="handleLayer1"
    >
      really long content ...
    </div>

Here is a complete reproduction https://stackblitz.com/edit/vitejs-vite-dtxxqa?file=src/App.vue

CodePudding user response:

To make my explanation easier I'll need to give each of the divs names. Let's call the absolutely positioned div topDiv, and the divs underneath downDivs.

You're also going to need a click handler on topDiv itself. That handler is what we will use to "forward" the event to the downDivs.

In your topDiv click handler, you'd do something like this:

// first hide the `topDiv`
event.target.hidden = true;

// Get the element underneath that also falls under the click location
let downDiv = document.elementFromPoint(event.clientX, event.clientY);

// Unhide the topDiv
event.target.hidden = false;

// We still need to confirm that the element gotten is actually a downDiv
if (!downDiv.classList.includes('down-div'))
    return;

// Now we can dispatch a duplicate click event on the downDiv
downDiv.dispatchEvent(new MouseEvent('click', {
    bubbles: true,
    pageX: event.pageX,
    pageY: event.pageY,
    clientX: event.clientX,
    clientY: event.clientY,
}));

// Now you can handle the clicks on the downDiv anyway you like :)

You can read this article to learn more about event dispatching

  • Related