Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当鼠标位于Firefox中嵌入的iframe上时,防止父页面滚动_Javascript_Firefox_Iframe_Jquery Events_Mousewheel - Fatal编程技术网

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

Javascript 当鼠标位于Firefox中嵌入的iframe上时,防止父页面滚动,javascript,firefox,iframe,jquery-events,mousewheel,Javascript,Firefox,Iframe,Jquery Events,Mousewheel,…无需限制iframe内的滚动,也无需专门命名/标记所有可滚动元素。 想象一下嵌入在父页面中的谷歌地图小部件。当您放大小部件时,显然不希望父页面滚动 我想我的答案解决了这个问题: 当在iframe中滚动时,主体不知道关于 那里发生了什么。但当iframe滚动条到达底部或 顶部,它将滚动传递到主体 取消从iframe传播的事件 但该解决方案在Firefox中不起作用,因为Firefox不会将iframe捕获的事件传播到父页面,但奇怪的是,它会滚动父页面。看 那么,在Firefox中,当用户在嵌入式

…无需限制iframe内的滚动,也无需专门命名/标记所有可滚动元素。

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

我想我的答案解决了这个问题:

当在iframe中滚动时,主体不知道关于 那里发生了什么。但当iframe滚动条到达底部或 顶部,它将滚动传递到主体

取消从iframe传播的事件

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


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

考虑到所有的先决条件,我认为以下是在Firefox中实现这一点的最明智的方法

使用稍微短一点的
div
将您的
iframe
包装起来,以便在其中启用垂直滚动:

<div id="wrapper" style="height:190px; width:200px; overflow-y: auto; overflow-x: hidden;">
  <iframe id="iframeid" height="200px" width="200px" src="about:blank">
  </iframe>
</div>
再加上你之前对Chrome的修复,它应该涵盖所有主要浏览器。以下是一个工作示例-


唯一未解决的问题是包装器
div
上的可见垂直滚动条。有几种方法可以解决这个问题,例如-

我认为这会解决你的问题 它解决了我的问题

    var myElem=function(event){
  return $(event.toElement).closest('.slimScrollDiv')
}

$(document).mouseover(function(e){
     window.isOnSub=myElem(e).length>0



})

$(document).on('mousewheel',function(e){
  if(window.isOnSub){  
console.log(e.originalEvent.wheelDelta);      
    if( myElem(e).prop('scrollHeight')-myElem(e).scrollTop()<=myElem(e).height()&&(e.originalEvent.wheelDelta<0)){

      e.preventDefault()
    } 


}

})
var myElem=函数(事件){
返回$(event.toElement).closest('.slimScrollDiv')
}
$(文档).mouseover(函数(e){
window.isOnSub=myElem(e).length>0
})
$(文档).on('mouseweell',函数(e){
if(window.isOnSub){
控制台.日志(如OriginaleEvent.wheelDelta);

如果(myElem(e).prop('scrollHeight')-myElem(e).scrollTop(),因为它是Firefox中的一个bug,解决方法是直接使用
scroll
事件,而不是
mouseweel
/
DOMMouseScroll
事件

我的做法是:当用户在
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);
我创建了一个立即执行的函数,以防止在全局范围内定义
s
变量

小提琴演奏:


编辑 由于您的问题没有使用jQuery标记(尽管在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);

因为Firefox使用DOMMouseScroll事件,我会尝试将$('body')更改为$(document),也许它可以工作,但我不确定。值得一试try@GOSCHEN这不是问题所在,“Firefox不会通过设计将iframe捕获的事件传播到父页面”,如果您仍然可以捕获滚动事件(在父页面上),也许你可以对照iframe的位置检查鼠标的位置:如果鼠标在里面,取消滚动我不明白,这不仅会阻止父对象的滚动,还会阻止子对象的滚动。你可以编辑我的JSFIDLE并告诉我你的解决方案是如何工作的吗?谢谢你的评论,请再次检查我的答案我有edit itI很抱歉,我应该更清楚,我见过类似的解决方案,但这取决于是否需要专门命名/标记要滚动的元素。这种方法容易出错且不可缩放。我在最初的问题中将此作为一个条件,但在这个问题中忘了再次提及。我现在进行了编辑以提及它.这是非常优雅的黑客行为!@Buzinas我希望父页面滚动,即使我的鼠标在iframe上,但在firefox中也不会发生,请看这个提琴谢谢,这项工作非常好!=D我已经重构了一些您的第一个代码,但我只更改了事件的处理方式。我将它们做成这样:`$('my_容器')。on('mouseenter','iframe',function(){}')
(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);
(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);