2012-04-18 115 views

回答

41

找到解决方案。

http://jsbin.com/itajok

这就是我所需要的。

这是代码。

http://jsbin.com/itajok/edit#javascript,html

使用一个jQuery插件。


更新由于取消通知

jquery-mousewheel

添加三个参数(deltadeltaX,并deltaY) 到事件处理程序的旧的行为现在已经过时并将在稍后的 版本中删除。

然后,event.deltaY现在必须使用:

var toolbox = $('#toolbox'), 
    height = toolbox.height(), 
    scrollHeight = toolbox.get(0).scrollHeight; 

toolbox.off("mousewheel").on("mousewheel", function (event) { 
    var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0; 
    return !blockScrolling; 
}); 

Demo

+6

你的链接使用github的js和休息,因为内容类型等等等等这里这个工程:http://jsbin.com/itajok/207/ – 2013-09-02 20:17:11

+0

这两个jsbins似乎并没有在Chrome设备模拟器和在苹果手机。有谁知道这是否仍然有效? – 2015-06-11 07:51:15

+2

您的“解决方案”仅适用于鼠标滚动事件,不适用于页面向上/向下或箭头键。 – Scott 2016-06-22 21:33:22

0

如果您将overflow: hidden风格应该走

编辑:其实我看了你的问题错了,只会隐藏滚动条,但我不认为这是你在找什么。

<div onmouseover="document.body.style.overflow='hidden';" onmouseout="document.body.style.overflow='auto';"></div> 
+1

我需要两个滚动条。我在谈论这个行为。当我滚动使用我的鼠标轨迹球达到div的滚动结束时,它不能滚动整个页面。 – Jeevan 2012-04-18 14:16:34

66

你可以做这样的事情灭活整个页面的滚动?

E.g.该HTML

<div onmouseover="disableBodyScroll();" onmouseout="enableBodyScroll();"> 
    content 
</div> 

然后的JavaScript像这样:

var body = document.getElementsByTagName('body')[0]; 
function disableBodyScroll() { 
    body.style.overflowY = 'hidden'; 
} 
function enableBodyScroll() { 
    body.style.overflowY = 'auto'; 
} 
+30

不错,但是当你将鼠标悬停在div上时,它会使浏览器的滚动条消失。 – cstack 2012-08-09 19:26:44

+0

@cstack你是对的,这就是为什么OP(Jeevan)自己的答案更好。 – 2014-07-04 07:03:40

+2

许多浏览器滚轮消失,现在基于用户移动鼠标重新出现,因此上述评论不再是问题。 – 2015-10-16 03:42:49

8

你可以在DIV上使用鼠标悬停事件禁用身体滚动条,然后mouseOut事件再次激活它:

+10

您也可以使用'document.body'。 – Ryan 2012-04-18 14:36:44

7

如果我正确理解你的问题,那么你要防止的主要内容滚动当鼠标移动到一个div(假设侧栏)。为此,侧栏可能不是主内容(它是浏览器窗口)的滚动容器的子项,以防止滚动事件冒泡到其父项。

这可能需要通过以下方式标记的一些变化:

<div id="wrapper"> 
    <div id="content"> 
    </div> 
</div> 
<div id="sidebar"> 
</div> 

看到它的工作在this sample fiddle和比较,与this sample fiddle具有侧边栏的一个稍微不同的鼠标离开的行为。请参阅scroll only one particular div with browser's main scrollbar

+0

在这种情况下,侧栏位于包装div外部。所以我不认为卷轴会冒泡给父母 – Jeevan 2012-04-19 05:03:28

+0

通过“这种情况”你的意思是你的情况?如果不是的话:你完全正确。如果是这样的话:如果你的页面在div滚动结束时滚动,那么滚动消息会冒泡到div父级,所以我认为你的页面和div不是兄弟,而是父母和孩子。 – NGLN 2012-04-19 06:22:17

+0

是的,页面是我的div的父母,所以在到达最后时,它开始滚动页面,我不想这样做。 – Jeevan 2012-04-19 08:06:15

15

所选解决方案是艺术作品。认为这是值得的一个插件....

$.fn.scrollGuard = function() { 
    return this 
     .on('wheel', function (e) { 
      var event = e.originalEvent; 
      var d = event.wheelDelta || -event.detail; 
      this.scrollTop += (d < 0 ? 1 : -1) * 30; 
      e.preventDefault(); 
     }); 
};  

这一直是我的一个持续的不便,并与我见过的其他黑客这个解决方案是那么干净。很想知道它是如何工作的,以及它会得到多大的支持,但是欢迎Jeevan和最初想到这个的人。顺便说一句 - stackoverflow的答案编辑器需要这个!

UPDATE

我相信这是因为它并不试图在所有操作DOM更好,只有防止起泡有条件...

$.fn.scrollGuard2 = function() { 
    return this 
    .on('wheel', function (e) { 
     var $this = $(this); 
     if (e.originalEvent.deltaY < 0) { 
     /* scrolling up */ 
     return ($this.scrollTop() > 0); 
     } else { 
     /* scrolling down */ 
     return ($this.scrollTop() + $this.innerHeight() < $this[0].scrollHeight); 
     } 
    }) 
    ; 
};  

工程在铬和许多伟大的比其他解决方案更简单...让我知道它是如何票价别处......

FIDDLE

+3

添加DOMMouseScroll事件使其与Firefox一起工作→http://jsfiddle.net/chodorowicz/egqy7mbz/1/ – chodorowicz 2015-07-03 17:35:20

+0

我很惊讶这不是写入jquery。我认为其中一个要点并不在乎你使用的浏览器。 – robisrob 2015-12-14 17:09:56

+0

实际上它看起来像两个都不赞成... ['wheel' event](https://developer.mozilla.org/en-US/docs/Web/Events/wheel) – robisrob 2015-12-14 17:12:06

2

您可以通过做这样的事情来禁用整个页面的滚动,但显示滚动条!

<div onmouseover="document.body.style.overflow='hidden'; document.body.style.position='fixed';" onmouseout="document.body.style.overflow='auto'; document.body.style.position='relative';"></div> 
+1

完美工作@joseantgv – 2018-02-09 08:58:25

7

我写了解决此问题

var div; 
    div = document.getElementsByClassName('selector')[0]; 

    div.addEventListener('mousewheel', function(e) { 
    if (div.clientHeight + div.scrollTop + e.deltaY >= div.scrollHeight) { 
     e.preventDefault(); 
     div.scrollTop = div.scrollHeight; 
    } else if (div.scrollTop + e.deltaY <= 0) { 
     e.preventDefault(); 
     div.scrollTop = 0; 
    } 
    }, false); 
+0

这里的几个解决方案之一,没有页面元素恼人地跳跃,因为溢出隐藏被设置。 – 2015-11-11 14:55:43

+0

+1这是一个可靠的解决方案。如果你将它附加到一个可滚动的容器中,你会希望在这个例子中的div是'e.currentTarget'。 – Matt 2016-12-04 11:26:49

+0

很干净的解决方案。谢谢 – 2017-06-14 14:57:04

2
$this.find('.scrollingDiv').on('mousewheel DOMMouseScroll', function (e) { 
    var delta = -e.originalEvent.wheelDelta || e.originalEvent.detail; 
    var scrollTop = this.scrollTop; 
    if((delta < 0 && scrollTop === 0) || (delta > 0 && this.scrollHeight - this.clientHeight - scrollTop === 0)) { 
    e.preventDefault(); 
    } 
}); 
2

如果输入选择器元素此禁用窗口上的滚动。 的作品像魅力。

elements = $(".selector"); 

elements.on('mouseenter', function() { 
    window.currentScrollTop = $(window).scrollTop(); 
    window.currentScrollLeft = $(window).scrollTop(); 
    $(window).on("scroll.prevent", function() { 
     $(window).scrollTop(window.currentScrollTop); 
     $(window).scrollLeft(window.currentScrollLeft); 
    }); 
}); 

elements.on('mouseleave', function() { 
    $(window).off("scroll.prevent"); 
}); 
1

基于CEED的答案,这里是一个版本,它允许嵌套滚动把守的元素。只有鼠标结束的元素才会滚动,并且滚动得非常顺利。这个版本也是可重入的。它可以在同一个元素上多次使用,并将正确删除并重新安装处理程序。使用

jQuery.fn.scrollGuard = function() { 
    this 
     .addClass('scroll-guarding') 
     .off('.scrollGuard').on('mouseenter.scrollGuard', function() { 
      var $g = $(this).parent().closest('.scroll-guarding'); 
      $g = $g.length ? $g : $(window); 
      $g[0].myCst = $g.scrollTop(); 
      $g[0].myCsl = $g.scrollLeft(); 
      $g.off("scroll.prevent").on("scroll.prevent", function() { 
       $g.scrollTop($g[0].myCst); 
       $g.scrollLeft($g[0].myCsl); 
      }); 
     }) 
     .on('mouseleave.scrollGuard', function() { 
      var $g = $(this).parent().closest('.scroll-guarding'); 
      $g = $g.length ? $g : $(window); 
      $g.off("scroll.prevent"); 
     }); 
}; 

一个简单的方法是增加一类,如scroll-guard,所有的页面,你能够滚动显示上的元素。然后使用$('.scroll-guard').scrollGuard()来保护他们。

0

我不能得到任何答案在Chrome和Firefox的工作,所以我想出了这个合并:

$someElement.on('mousewheel DOMMouseScroll', scrollProtection); 

function scrollProtection(event) { 
    var $this = $(this); 
    event = event.originalEvent; 
    var direction = (event.wheelDelta * -1) || (event.detail); 
    if (direction < 0) { 
     if ($this.scrollTop() <= 0) { 
      return false; 
     } 
    } else { 
     if ($this.scrollTop() + $this.innerHeight() >= $this[0].scrollHeight) { 
      return false; 
     } 
    } 
} 
4

这里是一个跨浏览器的方式做到这一点在Y轴上,它适用于桌面和移动设备。在OSX和iOS上测试。

var scrollArea = this.querySelector(".scroll-area"); 
scrollArea.addEventListener("wheel", function() { 
    var scrollTop = this.scrollTop; 
    var maxScroll = this.scrollHeight - this.offsetHeight; 
    var deltaY = event.deltaY; 
    if ((scrollTop === maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0)) { 
     event.preventDefault(); 
    } 
}); 

scrollArea.addEventListener("touchstart", function(event) { 
    this.previousClientY = event.touches[0].clientY; 
}); 

scrollArea.addEventListener("touchmove", function(event) { 
    var scrollTop = this.scrollTop; 
    var maxScroll = this.scrollHeight - this.offsetHeight; 
    var currentClientY = event.touches[0].clientY; 
    var deltaY = this.previousClientY - currentClientY; 
    if ((scrollTop === maxScroll && deltaY > 0) || (scrollTop === 0 && deltaY < 0)) { 
     event.preventDefault(); 
    } 
    this.previousClientY = currentClientY; 
}); 
+0

这个工程真棒!哇,正是我所搜索的,它需要绝对更多upvotes。 – delato468 2017-09-01 14:16:24

+0

此解决方案工作得很好,但需要很少调整: 需要通过'scrollTop> = maxScroll'来更改'scrollTop === maxScroll'。 对于1个案例来说,这似乎很奇怪。 – 2017-12-21 11:32:52