这是一个有趣的问题。
此解决方案将 div 放入数组中,并记住上次滚动到的元素的数组索引。一旦触发了滚动事件,它就会检查新的 scrollTop 是否高于或低于当前 div 的顶部偏移量,并相应地移动到数组中的下一个或上一个 div。
此解决方案允许您拥有许多 div。我试图消除滚动到快速时出现的闪烁,但我认为唯一的方法是在动画期间禁用滚动条。
http://jsfiddle.net/dUVmh/35/
$(function() {
var divs = [],
body = $('body, html'),
currentDiv = 0,
timeout;
$('div').each(function() {
divs.push($(this));
});
// we only need to capture the first scroll event triggered and then
// add another listener once we have done our animation
var scrollListen = function() {
$(window).one('scroll', function() {
doScroll($(this).scrollTop());
});
};
// Without the timeout, the scroll event would be triggered again too soon
var scrollEnd = function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
scrollListen();
}, 10);
};
// checks if the scroll direction was up and down and animates
// the body scrollTop to the next or previous div
var doScroll = function(scrollTop) {
var direction = scrollTop - divs[currentDiv].offset().top;
if (direction > 0 && currentDiv + 1 < divs.length) {
nextDiv = currentDiv + 1;
} else if (currentDiv - 1 > -1) {
nextDiv = currentDiv - 1;
}
if (currentDiv === nextDiv) {
scrollEnd();
}
body.animate({
scrollTop: divs[nextDiv].offset().top
}, 1000, function() {
currentDiv = nextDiv;
scrollEnd();
});
};
scrollListen();
});
编辑:Firefox scrollTop 需要在 html 而不是 body 上进行更改。还修复了 firefox 一次多次调用 scrollListen 的问题。