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

vsy*_*ync 55 html javascript jquery events scroll

我有一个包含一个iframe一个模式对话框窗口(弹出),
以及里面的iframe有一个DIV是滚动的.

当我滚动iframe的内部DIV,并且它已达到其上限或下限时,
浏览器本身的窗口开始滚动.这是一种不受欢迎的行为.

我尝试过这样的东西,当
onMouseEnter鼠标进入弹出框区域时会杀死主窗口滚动:

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

$("#popup").mouseenter(function(){
   $(window).bind("scroll", function(e){
        e.preventDefault();
   }); 
}).mouseleave(function(){
    $(window).unbind("scroll");
});
Run Code Online (Sandbox Code Playgroud)

更新

好像现在在2013年e.preventDefault();就够了......

bob*_*nce 26

对不起,据我所知,不可能取消任何类型的滚动事件.

无论W3MSDN说:

Cancelable  No
Bubbles     No
Run Code Online (Sandbox Code Playgroud)

我认为你不得不把它留给浏览器作者修复.Firefox(无论如何,在Linux上为3.5)对我来说似乎有一个更好的行为:如果孩子在你开始使用滚轮时已经在顶端/底端,它只会滚动父对象.

  • 它可以完成 - 而且相对简单:http://stackoverflow.com/questions/5802467/prevent-scrolling-of-parent-element (4认同)

Chr*_*ter 17

如果我们无法阻止窗口滚动,为什么不撤消它呢?也就是说,捕捉滚动事件然后滚动回固定位置.

只要有一个悬停在以下代码,以下代码就会锁定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;
});
Run Code Online (Sandbox Code Playgroud)

我将它用于http://bundestube.de/上的查询建议框 (在顶部搜索框中输入一些字符以使可滚动窗格可见):

截图

这在Chrome/Safari(Webkit)中完美无缺,在Firefox和Opera中有一些滚动故障.出于某种原因,它不适用于我的IE安装.我想这与jQuery的悬停方法有关,这种方法似乎在100%的情况下都无法正常工作.


vsy*_*ync 6

使用简单的CSS属性解决了(对于某些浏览器):
overscroll-behavior

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;
}
Run Code Online (Sandbox Code Playgroud)
<section>
 <input value='end' />
</section>
Run Code Online (Sandbox Code Playgroud)

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


与上面相同的演示,但没有技巧:

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

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

section::before{
  content: '';
  height: 200%;
  display: block;
}
Run Code Online (Sandbox Code Playgroud)
<section>
 <input value='end' />
</section>
Run Code Online (Sandbox Code Playgroud)

  • “过度滚动行为”可以成为救星。不幸的是,Safari 还不支持它。 (3认同)