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

发布于 2025-01-29 13:48:56 字数 1928 浏览 1 评论 0 原文

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

基础层具有不同的单击处理程序的不同部分。图片中的框(x,y,z)。

如何在将滚动放在顶层的同时,如何为基础层有一个点击处理程序?

我尝试过CSS Pointer-events:none; ,但它转发了所有事件, 这会导致顶层滚动的滚动。

我尝试使用JavaScript手动手动,但是 事件采购无法正常工作。

这是此处的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>

是一个完整的复制

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鹊巢 2025-02-05 13:48:56

为了使我的解释更容易,我需要给每个Divs名称。让我们调用绝对位置的Div TopDiv ,然后在 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 :)

您可以阅读本文以了解有关事件派遣

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文