【问题标题】:Pass mouse events through absolutely-positioned element通过绝对定位元素传递鼠标事件
【发布时间】:2010-11-03 19:55:48
【问题描述】:

我正在尝试在一个元素上捕获鼠标事件,该元素上还有另一个绝对定位的元素。

现在,绝对定位元素上的事件命中它并冒泡到它的父级,但我希望它对这些鼠标事件是“透明的”并将它们转发到它后面的任何东西。我应该如何实现这个?

【问题讨论】:

    标签: javascript html dom events dom-events


    【解决方案1】:

    您没有收到该事件的原因是因为绝对定位的元素不是您想要“单击”的元素(蓝色 div)的子元素。我能想到的最简洁的方法是将绝对元素作为您想要单击的元素的子元素,但我假设您不能这样做,否则您不会在这里发布这个问题:)

    另一种选择是为绝对元素注册一个单击事件处理程序并为蓝色 div 调用单击处理程序,使它们都闪烁。

    由于事件通过 DOM 冒泡的方式,我不确定您是否有更简单的答案,但我很好奇是否有其他人有任何我不知道的技巧!

    【讨论】:

    • 感谢 Loktar 的回复。不幸的是,在实际页面上,我不会知道绝对定位元素下面是什么,并且可能有多个目标。我能想到的唯一解决方法是抓取鼠标坐标并将它们与可能的目标进行比较,看看它们是否相交。那简直太恶心了。
    【解决方案2】:

    如果您只需要鼠标按下,您可以使用document.elementFromPoint 方法,通过:

    1. 在 mousedown 时移除顶层,
    2. xy 坐标从事件传递到 document.elementFromPoint 方法以获取下面的元素,然后
    3. 恢复顶层。

    【讨论】:

    • 这里有更多冗长的解释:vinylfox.com/forwarding-mouse-events-through-layers
    • 太棒了,我什至不知道这种方法存在!它也可以很容易地使用 while 循环来获取光标下的所有元素,以获取最顶部的元素,然后将其隐藏以查找下一个元素。在这里获取我的版本:gist.github.com/Pichan/5498404
    • 这个变通办法的问题是它不适用于缩放页面。对于移动设备或桌面浏览器,放大 X Y 坐标不再意味着什么,也没有明确的方法来计算缩放。我相信捏缩放实际上是不可能的。
    【解决方案3】:
    pointer-events: none;
    

    是一个 CSS 属性,它使事件“通过”应用该属性的 HTML 元素。它使事件发生在“下面”的元素上。

    详情见:https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events

    几乎所有浏览器都支持,包括IE11; 21 年 5 月全球支持率约为 98.2%):http://caniuse.com/#feat=pointer-events(感谢 @s4y 在 cmets 中提供链接)。

    【讨论】:

    • 谢谢!这是现代(和非 IE)浏览器的完美解决方案。在发布这个问题时,我认为pointer-events 不存在!我可能会在某个时候将接受的答案切换到这个答案。
    • 哇,这只是节省了我几个小时。
    • 我刚刚将接受的答案切换为这个答案。支持pointer-eventsstill isn’t super awesome,不过越来越好了。对于更兼容的选项,请使用@JedSchmidt 的答案。
    • 谢谢,我从来不知道这真的存在。它为我节省了几个小时
    • 但是,如果您只想让像滚动事件这样的事件通过而让顶部元素仍然响应所有其他事件,该怎么办。将 pointer-events 设置为 none 会杀死顶部元素上的所有事件。
    【解决方案4】:

    如果您知道需要鼠标事件的元素,并且您的叠加层是透明的,您可以将它们的 z-index 设置为高于叠加层的值。在这种情况下,所有事件当然应该在所有浏览器上都有效。

    【讨论】:

      【解决方案5】:

      有一个可用的 javascript 版本可以手动将事件从一个 div 重定向到另一个。

      我把它清理了,做成了一个 jQuery 插件。

      这是 Github 存储库: https://github.com/BaronVonSmeaton/jquery.forwardevents

      不幸的是,我使用它的目的 - 在 Google 地图上覆盖蒙版并没有捕获点击和拖动事件,并且鼠标光标不会改变,这会降低用户体验,我只是决定在 IE 下隐藏蒙版和 Opera - 两个不支持指针事件的浏览器。

      【讨论】:

        【解决方案6】:

        也很高兴知道...
        可以为父元素(可能是透明的 div)禁用指针事件,但为子元素启用。 如果您使用多个重叠的 div 层,这将很有帮助,您希望能够单击任何层的子元素。为此,所有育儿 div 都获得 pointer-events: none 和 click-children 获得指针事件由 pointer-events: all 重新启用

        .parent {
            pointer-events:none;        
        }
        .child {
            pointer-events:all;
        }
        
        <div class="some-container">
           <ul class="layer-0 parent">
             <li class="click-me child"></li>
             <li class="click-me child"></li>
           </ul>
        
           <ul class="layer-1 parent">
             <li class="click-me-also child"></li>
             <li class="click-me-also child"></li>
           </ul>
        </div>
        

        【讨论】:

        • 太棒了,就在发现 pointer-events:none 的高潮和即将影响子节点的失望之后,你拯救了一天:)
        • ;) 对此非常高兴
        • 可以归结为:.parent * { pointer-events:all; } for children?
        • 应该是“pointer-events: auto;”。 “all”值仅适用于 SVG。见developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
        • @Dmitry 可以确认,确实有效:.parent { pointer-events:none; }.parent * { pointer-events:auto; }
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-03
        • 2021-09-14
        • 1970-01-01
        • 1970-01-01
        • 2021-06-22
        相关资源
        最近更新 更多