如何将特定事件转发到重叠的 DOM 元素

How to forward specific event to overlapped DOM element

我有两个完全重叠divs;顶层有滚动行为,因为它有溢出的内容,我想保持滚动行为。

底层有不同的部分,有不同的点击处理程序;图片中的方框 (X, Y, Z)。

如何在保持顶层滚动的同时为底层设置点击处理程序?

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.

这里是DOM结构

 <div>
    <div
      ref="layer2"
      class="
        layer2
        h-96
        cursor-pointer
        text-2xl text-center
        flex
        space-x-4
        items-center
        justify-center
        bg-green-400
      "
      style="width: 600px"
      @click="handleLayer2"
    >
      <div
        @click="handleSection('x')"
        class="w-[200px] h-[8rem] bg-red-600 shadow-lg rounded h-24"
      >
        X
      </div>
      <div
        @click="handleSection('y')"
        class="w-[200px] h-[8rem] bg-red-600 shadow-lg rounded h-24"
      >
        Y
      </div>
      <div
        @click="handleSection('z')"
        class="w-[200px] h-[8rem] bg-red-600 shadow-lg rounded h-24"
      >
        Z
      </div>
    </div>

    <div
      class="
        layer1
        absolute
        top-0
        left-0
        bg-pink-500
        h-96
        text-xl
        whitespace-nowrap
        text-center
        opacity-70
        overflow-scroll
        pt-64
      "
      style="width: 600px"
      @click="handleLayer1"
    >
      really long content ...
    </div>

这里是完整的复制品https://stackblitz.com/edit/vitejs-vite-dtxxqa?file=src/App.vue

为了让我的解释更容易,我需要给每个 div 的名字。我们称绝对定位的 div topDiv 和下面的 div 为 downDivs.

您还需要 topDiv 本身的点击处理程序。我们将使用该处理程序将事件“转发”到 downDivs.

在您的 topDiv 点击处理程序中,您将执行如下操作:

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

您可以阅读本文以了解有关 event dispatching

的更多信息