当鼠标悬停在 Firefox 中的嵌入式 iframe 上时防止父页面滚动
Prevent parent page from scrolling when mouse is over embedded iframe in Firefox
...不限制 iframe 内的滚动或需要专门 name/tag 所有可滚动元素。
想象一下 google 地图小部件嵌入在父页面中。显然,当您放大小部件时,您不希望父页面滚动。
我认为 的答案解决了问题:
While scrolling inside an iframe, the body doesn't know anything about
what happens there. But when iframe scroller reach the bottom or the
top, it pass scrolling to body.
Cancel the event that propagates from the iframe.
但是该解决方案在 Firefox 中不起作用,因为 Firefox 不会 - by design - propagate events captured by iframe to the parent page, yet strangely it will scroll the parent page. See jsfiddle here。
$('body').bind('mousewheel DOMMouseScroll', onWheel);
function onWheel (e){
if (e.target === iframe)
e.preventDefault();
console.log(e);
}
那么,当用户在 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>
现在您可以将 iframe
垂直居中并每次都重新定位
包装器收到一个 scroll
事件(当用户试图在框架边缘滚动时会发生):
var topOffset = 3;
wrapper.scrollTop(topOffset);
wrapper.on("scroll", function(e) {
wrapper.scrollTop(topOffset);
});
将此与您之前对 Chrome 的修复相结合,它应该涵盖所有主要浏览器。这是一个工作示例 - http://jsfiddle.net/o2tk05ab/5/
唯一突出的问题是包装器上可见的垂直滚动条 div
。有几种方法可以解决这个问题,例如 - Hide scroll bar, but still being able to scroll
我想这会解决你的问题
它解决了我的
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()
}
}
})
用您想要的元素选择器替换“.slimScrollDiv”
当你的鼠标在上面时防止父滚动
由于它是 Firefox 中的一个错误,解决方法是直接使用 scroll
事件,而不是 mousewheel
/ DOMMouseScroll
事件。
我的做法:当用户将鼠标移到 iframe
上时,我将标志设置为 true
,当他将鼠标移到那里时,我将其设置回 false
.
然后,当用户尝试滚动,但鼠标箭头位于 iframe 内时,我会阻止父 window 滚动。但是,不幸的是,你不能用通常的 e.preventDefault()
方法阻止 window 滚动,所以我们在这里仍然需要另一种解决方法,强制 window 精确滚动到 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
变量。
Fiddle 工作: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);
...不限制 iframe 内的滚动或需要专门 name/tag 所有可滚动元素。
想象一下 google 地图小部件嵌入在父页面中。显然,当您放大小部件时,您不希望父页面滚动。
我认为
While scrolling inside an iframe, the body doesn't know anything about what happens there. But when iframe scroller reach the bottom or the top, it pass scrolling to body.
Cancel the event that propagates from the iframe.
但是该解决方案在 Firefox 中不起作用,因为 Firefox 不会 - by design - propagate events captured by iframe to the parent page, yet strangely it will scroll the parent page. See jsfiddle here。
$('body').bind('mousewheel DOMMouseScroll', onWheel);
function onWheel (e){
if (e.target === iframe)
e.preventDefault();
console.log(e);
}
那么,当用户在 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>
现在您可以将 iframe
垂直居中并每次都重新定位
包装器收到一个 scroll
事件(当用户试图在框架边缘滚动时会发生):
var topOffset = 3;
wrapper.scrollTop(topOffset);
wrapper.on("scroll", function(e) {
wrapper.scrollTop(topOffset);
});
将此与您之前对 Chrome 的修复相结合,它应该涵盖所有主要浏览器。这是一个工作示例 - http://jsfiddle.net/o2tk05ab/5/
唯一突出的问题是包装器上可见的垂直滚动条 div
。有几种方法可以解决这个问题,例如 - Hide scroll bar, but still being able to scroll
我想这会解决你的问题 它解决了我的
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()
}
}
})
用您想要的元素选择器替换“.slimScrollDiv”
当你的鼠标在上面时防止父滚动
由于它是 Firefox 中的一个错误,解决方法是直接使用 scroll
事件,而不是 mousewheel
/ DOMMouseScroll
事件。
我的做法:当用户将鼠标移到 iframe
上时,我将标志设置为 true
,当他将鼠标移到那里时,我将其设置回 false
.
然后,当用户尝试滚动,但鼠标箭头位于 iframe 内时,我会阻止父 window 滚动。但是,不幸的是,你不能用通常的 e.preventDefault()
方法阻止 window 滚动,所以我们在这里仍然需要另一种解决方法,强制 window 精确滚动到 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
变量。
Fiddle 工作: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);