当Firefox中的鼠标嵌入iframe时,防止父页面滚动

dan*_*cek 11 javascript iframe firefox javascript-events mousewheel

...不限制iframe内的滚动或需要专门命名/标记所有可滚动元素.

想象一下嵌入在父页面中的谷歌地图小部件.放大窗口小部件时,显然不希望父页面滚动.

我以为我前一个问题的答案解决了这个问题:

在iframe内滚动时,身体对那里发生的事情一无所知.但是当iframe卷轴到达底部或顶部时,它会滚动到正文.

取消从iframe传播的事件.

但该解决方案在Firefox中不起作用,因为Firefox不会 - 按设计 - 将iframe捕获的事件传播到父页面,但奇怪的是它会滚动父页面.在这里看到jsfiddle.

$('body').bind('mousewheel DOMMouseScroll', onWheel);

function onWheel (e){
    if (e.target === iframe)
        e.preventDefault();
    console.log(e);
}
Run Code Online (Sandbox Code Playgroud)

那么,当用户在Firefox中缩放嵌入式iframe中的内容时,如何防止页面滚动?

Buz*_*nas 12

由于它是Firefox中的一个错误,因此解决方法是直接使用scroll事件而不是mousewheel/ DOMMouseScroll1.

我做的方式:当用户将鼠标移到上面时iframe,我设置了一个标志true,当他将鼠标移开时,我将其设置为false.

然后,当用户尝试滚动,但鼠标箭头在iframe内时,我阻止父窗口滚动.但是,遗憾的是,您无法使用常规e.preventDefault()方法阻止窗口滚动,因此我们仍需要另一种解决方法,强制窗口精确滚动到之前已经存在的X和Y位置.

完整代码:

(function(w) {
    var s = { insideIframe: false } 

    $(iframe).mouseenter(function() {
        s.insideIframe = true;
        s.scrollX = w.scrollX;
        s.scrollY = w.scrollY;
    }).mouseleave(function() {
        s.insideIframe = false;
    });

    $(document).scroll(function() {
        if (s.insideIframe)
            w.scrollTo(s.scrollX, s.scrollY);
    });
})(window);
Run Code Online (Sandbox Code Playgroud)

我已经创建了一个立即执行的函数来防止s在全局范围内定义变量.

小提琴工作:http://jsfiddle.net/qznujqjs/16/


编辑

由于你的问题没有用jQuery标记(尽管在其中,你已经使用库展示了代码),使用vanilla JS的解决方案就像上面那样简单:

(function(w) {
    var s = { insideIframe: false } 

    iframe.addEventListener('mouseenter', function() {
        s.insideIframe = true;
        s.scrollX = w.scrollX;
        s.scrollY = w.scrollY;
    });

    iframe.addEventListener('mouseleave', function() {
        s.insideIframe = false;
    });

    document.addEventListener('scroll', function() {
        if (s.insideIframe)
            w.scrollTo(s.scrollX, s.scrollY);
    });
})(window);
Run Code Online (Sandbox Code Playgroud)