我添加这个答案是为了完整性,因为@amustill 接受的答案没有正确解决 Internet Explorer 中的问题。有关详细信息,请参阅我原帖中的评论。此外,这个解决方案不需要任何插件——只需要 jQuery。
本质上,代码通过处理mousewheel
事件来工作。每个这样的事件包含一个wheelDelta
等于px
它要将可滚动区域移动到的数量。如果此值为>0
,则我们正在滚动up
。如果wheelDelta
是,<0
那么我们正在滚动down
。
FireFox:FireFoxDOMMouseScroll
用作事件并填充originalEvent.detail
,其+/-
与上述内容相反。它通常返回 的间隔3
,而其他浏览器以 的间隔返回滚动120
(至少在我的机器上)。为了纠正,我们简单地检测它并乘以-40
归一化。
如果<div>
的可滚动区域已经位于顶部或底部的最大位置,@amustill 的回答通过取消事件来起作用。但是,在大于剩余可滚动空间的情况下,Internet Explorer会忽略已取消的事件delta
。
换句话说,如果您有一个包含可滚动内容的200px
tall并且当前is ,则告诉浏览器进一步滚动的事件将导致 the和滚动,因为+ > 。<div>
500px
scrollTop
400
mousewheel
120px
<div>
<body>
400
120
500
所以——为了解决这个问题,我们必须做一些稍微不同的事情,如下图:
必要的jQuery
代码是:
$(document).on('DOMMouseScroll mousewheel', '.Scrollable', function(ev) {
var $this = $(this),
scrollTop = this.scrollTop,
scrollHeight = this.scrollHeight,
height = $this.innerHeight(),
delta = (ev.type == 'DOMMouseScroll' ?
ev.originalEvent.detail * -40 :
ev.originalEvent.wheelDelta),
up = delta > 0;
var prevent = function() {
ev.stopPropagation();
ev.preventDefault();
ev.returnValue = false;
return false;
}
if (!up && -delta > scrollHeight - height - scrollTop) {
// Scrolling down, but this will take us past the bottom.
$this.scrollTop(scrollHeight);
return prevent();
} else if (up && delta > scrollTop) {
// Scrolling up, but this will take us past the top.
$this.scrollTop(0);
return prevent();
}
});
本质上,该代码可以取消任何滚动事件这将创建不希望的边缘条件,则用了jQuery设置scrollTop
的<div>
到最大值或最小值,这取决于哪个方向mousewheel
事件请求。
因为事件在任何一种情况下都被完全取消,所以它根本不会传播到body
,因此解决了 IE 以及所有其他浏览器中的问题。
我还在jsFiddle 上提供了一个工作示例。