【问题标题】:Dispatch mouse wheel event on another DOM element在另一个 DOM 元素上调度鼠标滚轮事件
【发布时间】:2013-03-09 10:35:58
【问题描述】:

我有一个带有可滚动 div 的网页。 在可滚动 div 之上,我绝对定位了与可滚动 div 的一半重叠的 div。

当我将鼠标光标放在可滚动的 div 上时,我可以用鼠标滚轮滚动它。但是当我将光标移到重叠的 div 上时,鼠标滚轮会停止滚动该 div(这是正确的行为,因为绝对定位的 div 不在可滚动的 div 内)。

问题:如何将绝对定位的 div 接收到的滚动事件传递或分派给这个底层的可滚动 div,以使这个绝对定位的 div 对鼠标滚轮事件“透明”。

我可以让它在 Chrome 中运行,但不能在 IE 和 Firefox 中运行。 如何重写此代码以使其在 IE 和 Firefox 中运行?

if ($.browser.webkit) {    
    $(".overlap-container").bind("mousewheel", function (e) {

        var origEvent = e.originalEvent;
        var evt = document.createEvent("WheelEvent");
        evt.initWebKitWheelEvent(
        origEvent.wheelDeltaX,
        origEvent.wheelDeltaY,
        window,
        0,
        0,
        0,
        0,
        origEvent.ctrlKey,
        origEvent.altKey,
        origEvent.shiftKey,
        origEvent.metaKey);

        $(".scroll-container").get(0).dispatchEvent(evt);
    });
}

请参见此处的示例: http://jsfiddle.net/HAc4K/5

已编辑:此问题最初来自 jqGrid - 冻结的列不会对鼠标滚轮滚动做出反应。

在 Chrome 和 Firefox 中支持很棒的 CSS 属性:pointer-events:none

【问题讨论】:

    标签: javascript html dom


    【解决方案1】:

    看起来像是 jQuery 的一个已知问题:OriginalEvent not supported in IE

    【讨论】:

    • 这里jsfiddle.net/HAc4K/5是没有originalEvent的更新版本
    【解决方案2】:

    简短的回答:在使用 Internet Explorer 的情况下,您在 the demo 中使用了错误的 initWheelEvent 参数。该方法应该有the documentation 中描述的16 个参数。你目前只使用了11个参数相同的initWebKitWheelEvent,但initWheelEvent的所有参数的含义绝对是另一回事。你必须修复initWheelEvent的参数。

    【讨论】:

    • 这里是更改版本jsfiddle.net/HAc4K/5,带有该文档中的参数,并且没有使用 originalEvent。我尝试了很多不同的参数集,但都没有成功。
    【解决方案3】:

    使用RetargetMouseScroll(overlap container, scroll container)

    【讨论】:

    • 此库仅适用于window 目标,不适用于 HTMLElement。但经过一些编辑后,它开始工作。这不是真正的重定向,而是接近它——至少这个库正确地计算了像素中的滚动移位量——所以滚动左右部分的外观没有区别。
    • 顺便说一句,更改是:在第 34 行替换 targetWindow.scrollBy(0, scrollAmount); with { if (targetWindow.scrollBy) targetWindow.scrollBy(0, scrollAmount); else if (targetWindow.scrollByLines) targetWindow.scrollByLines(scrollAmountLines);否则 targetWindow.scrollTop = targetWindow.scrollTop + scrollAmount; }
    • 谢谢,我会考虑将其添加到库中。
    【解决方案4】:

    我意识到这不是您正在寻找的,但至少在 Chrome、IE7+ 和 Firefox 3.5+ 中,这可以满足您的要求 - 当覆盖它的 div 接收滚动事件时滚动底层 div:

    http://jsfiddle.net/b9chris/yM3qs/

    这样做只是因为重叠的 div 是它重叠的 div 的子级 - 没有 jquery 传递任何鼠标滚轮事件(尽管它正在监听滚动以确保重叠的 div 保持在需要的位置)。

    然而,在 jqGrid 中实现这种解决方法可能需要在其中修改相当多的代码。

    HTML:

    <div id=under>
        (content goes here)
        <div id=over></div>
    </div>
    

    CSS:

    #under {
        position: absolute;
        left: 0; top: 0;
        width: 220px; height: 200px;
        overflow-y: scroll;
    }
    
    #over {
        position: absolute;
        left: 1px; top: 100px;
        width: 200px; height: 100px;
        z-index: 2;
    }
    

    JS:

    (function() {
        $('#under').on('scroll', function() {
            $('#over').css('top', $(this).scrollTop() + 100);
        });
    })();
    

    【讨论】:

      【解决方案5】:

      这是2019年重叠容器获取轮子事件的解决方案:

      document.querySelector('.overlap').on('wheel', (e) => {
        const overlap = e.target
      
        overlap.style.pointerEvents = 'none'
        setTimeout(() => {overlap.style.pointerEvents = 'auto'}, 0)
      })
      

      这样 overlapped 元素会从名为 .overlapoverlapping 元素获取轮子事件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-03
        • 1970-01-01
        • 2014-12-30
        相关资源
        最近更新 更多