防止滚动从一个元素冒泡到另一个窗口

我有一个模态框窗口(弹出窗口) ,其中包含一个 iframe,
在这个 Iframe里面有一个可滚动的 Div

当我滚动 iframe 的内部 DIV,并且它已经达到它的顶部或底部限制时,浏览器本身的窗口开始滚动。这是 不受欢迎的行为

我曾经试过类似的方法,当鼠标进入弹出框区域时,它会停止主窗口滚动:

由于某些原因 e.preventDefault()不能正常工作。

$("#popup").mouseenter(function(){
$(window).bind("scroll", function(e){
e.preventDefault();
});
}).mouseleave(function(){
$(window).unbind("scroll");
});
59706 次浏览
function stopPropogation(e)
{
e = e || window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
}

这个应该可以。

显然,你可以设置 overflow:hidden防止滚动。如果文件已经滚动了,不知道会怎么样。我还使用一台没有鼠标的笔记本电脑,所以今晚不用滚轮测试了: ——不过这可能值得一试。

抱歉,据我所知,不可能取消任何滚动事件。

W3MSDN都表示:

Cancelable  No
Bubbles     No

我认为你必须把这个问题留给浏览器作者来解决。Firefox (Linux 上的3.5)对我来说似乎有更好的表现: 只有当你使用滚轮 开始的时候,孩子已经在顶部/底部的时候,它才会滚动父节点。

您可以尝试在 iframe 内部使用 jscroll 面板来替换默认滚动条。

Http://www.kelvinluck.com/assets/jquery/jscrollpane/jscrollpane.html

我不确定,但是试一试吧

如果我们不能防止窗口滚动,为什么不撤消它? 也就是说,捕获滚动事件,然后滚动回固定位置。

下面的代码锁定的 Y 轴,只要一个盘旋在 $("#popup"):

// here we store the window scroll position to lock; -1 means unlocked
var forceWindowScrollY = -1;


$(window).scroll(function(event) {
if(forceWindowScrollY != -1 && window.scrollY != forceWindowScrollY) {
$(window).scrollTop(forceWindowScrollY);
}
});


$("#popup").hover(function() {
if(forceWindowScrollY == -1) {
forceWindowScrollY = $(window).scrollTop();
}
}, function() {
forceWindowScrollY = -1;
});

我在 http://bundestube.de/的查询建议框中使用了这个选项(在顶部搜索框中输入一些字符,使可滚动窗格可见) :

Screenshot

这个功能在 Chrome/Safari (Webkit)中完美无缺,在 Firefox 和 Opera 中也有一些滚动小故障。由于某些原因,它不工作与我的 IE 安装。我猜这与 jQuery 的 hover 方法有关,它似乎在所有情况下都不能正确工作。

我知道这是一个很老的问题,但是因为这是谷歌的顶级搜索结果之一... ... 我不得不在没有 jQuery 的情况下取消滚动冒泡,这段代码对我很有用:

function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}


document.getElementById('a').onmousewheel = function(e) {
document.getElementById('a').scrollTop -= e. wheelDeltaY;
preventDefault(e);
}

我的 jQuery 插件:

$('.child').dontScrollParent();


$.fn.dontScrollParent = function()
{
this.bind('mousewheel DOMMouseScroll',function(e)
{
var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;


if (delta > 0 && $(this).scrollTop() <= 0)
return false;
if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).height())
return false;


return true;
});
}

我是这么做的:

  $('.noscroll').on('DOMMouseScroll mousewheel', function(ev) {
var prevent = function() {
ev.stopPropagation();
ev.preventDefault();
ev.returnValue = false;
return false;
}
return prevent();
});

小提琴演奏

使用 CSS overflow:hidden来隐藏滚动条,因为如果他们拖动滚动条,它将什么也不做。

跨浏览器工作

新的网页开发人员在这里。这工作就像一个魅力为我在 IE 和 Chrome。

static preventScrollPropagation(e: HTMLElement) {
e.onmousewheel = (ev) => {
var preventScroll = false;
var isScrollingDown = ev.wheelDelta < 0;
if (isScrollingDown) {
var isAtBottom = e.scrollTop + e.clientHeight == e.scrollHeight;
if (isAtBottom) {
preventScroll = true;
}
} else {
var isAtTop = e.scrollTop == 0;
if (isAtTop) {
preventScroll = true;
}
}
if (preventScroll) {
ev.preventDefault();
}
}
}

不要让代码行的数量欺骗了你,它非常简单——只是为了可读性有点冗长(自我文档化代码 ftw 对吗?)

我想添加一点更新的代码,我发现最好的工作:

var yourElement = $('.my-element');


yourElement.on('scroll mousewheel wheel DOMMouseScroll', function (e) {
var delta = e.originalEvent.wheelDelta || -e.originalEvent.detail;


if (delta > 0 && $(this).scrollTop() <= 0)
return false;
if (delta < 0 && $(this).scrollTop() >= this.scrollHeight - $(this).outerHeight())
return false;


return true;
});

这个元素和上面已经提到的元素之间的区别在于添加了更多的事件,并且使用了 外高()而不是 身高(),以避免在元素有填充时崩溃!

$('.scrollable').on('DOMMouseScroll mousewheel', function (e) {
var up = false;
if (e.originalEvent) {
if (e.originalEvent.wheelDelta) up = e.originalEvent.wheelDelta / -1 < 0;
if (e.originalEvent.deltaY) up = e.originalEvent.deltaY < 0;
if (e.originalEvent.detail) up = e.originalEvent.detail < 0;
}


var prevent = function () {
e.stopPropagation();
e.preventDefault();
e.returnValue = false;
return false;
}


if (!up && this.scrollHeight <= $(this).innerHeight() + this.scrollTop + 1) {
return prevent();
} else if (up && 0 >= this.scrollTop - 1) {
return prevent();
}
});

这就是我解决问题的方法:

当我打开弹出窗口时,我调用以下命令:

$('body').css('overflow','hidden');

然后,当我关闭弹出窗口时,我称之为:

$('body').css('overflow','auto');

弹出窗口是模态的,因此不需要与底层主体进行交互

效果很好

从现在开始到2018年及以后,防止违约就足够了。

$('.elementClass').on("scroll", function(e){
e.preventDefault();
});

这将防止滚动到父级。

使用简单的 CSS 属性解决(对于 一些浏览器) : < br > 超滚动-行为:

奥托 默认的滚动溢出行为正常发生。

包容 默认的滚动溢出行为是在设置了这个值的元素中观察到的(例如“弹出”效果或刷新) ,但是相邻的滚动区域没有发生滚动链接,例如底层元素不会滚动。

没有 相邻滚动区域没有发生滚动链接,并且防止默认滚动溢出行为。

body{
height: 600px;
overflow: auto;
}


section{
width: 50%;
height: 50%;
overflow: auto;
background: lightblue;
overscroll-behavior: none; /*   <--- the trick    */
}


section::before{
content: '';
height: 200%;
display: block;
}
<section>
<input value='end' />
</section>

只需要将该样式属性应用到滚动应该“锁定”的元素上,滚动事件就不会冒泡出现在任何可能也有滚动的父元素上。


同样的演示,但 没有的技巧:

body{
height: 600px;
overflow: auto;
}


section{
width: 50%;
height: 50%;
overflow: auto;
background: lightblue;
}


section::before{
content: '';
height: 200%;
display: block;
}
<section>
<input value='end' />
</section>

试试下面的代码:

var container = document.getElementById('a');
container.onwheel = (e) => {
const deltaY = e.wheelDeltaY || -(e.deltaY * 25); // Firefox fix
container.scrollTop -= deltaY;
e.preventDefault();
e.stopPropagation();
e.returnValue = false;
};