我正在寻求实现像 Google Inbox landing page 这样的滚动功能有:
值得注意的是,无论您滚动滚轮的速度有多快或多少次,它都会算作“一”并进入下一步。这似乎说起来容易做起来难,因为无法取消“滚动”事件。有一种方法可以取消 DOMMouseScroll 和 mousewheel 事件,但是这样做很棘手:
问题是取消这些事件的工作方式如下所示,使用return PreventFn(ev)
:
var preventFn = function (ev) {
ev.returnValue = false;
return false;
};
但是这样做会导致 scrollTop()
操作中断。但如果没有它,滚动事件就会通过并弄乱它。
我可以通过使用超时的相当有缺陷的实现来做得更好(参见 fiddle )。它工作正常,但有一个主要错误,如果用户在 scrollTop()
动画发生时滚动,一切都会永久中断。
我该如何纠正这个问题,使其像 Google 一样出色? (最好没有超时。在 Google 页面中,从第 3 步到第 4 步......我什至无法感知任何超时,它似乎在我的鼠标滚轮开始移动时立即滚动。所以这似乎是可能的)
最佳答案
似乎解决方案意味着使用 anchor 和超时。
灵感来自this post
我已经更新了你的 plunkr。这是一个链接:http://plnkr.co/edit/GDdm7Z4OEzfh7ZwnQce7?p=preview
app.directive('autoScroll', function($document, $timeout) {
return {
restrict: 'AE',
link: function(scope, elem, attrs) {
var delay = false;
$document.on('mousewheel DOMMouseScroll', function(e) {
e.preventDefault();
if (delay) return;
delay = true;
$timeout(function() {
delay = false
}, 100)
var wd = e.originalEvent.wheelDelta || -e.originalEvent.detail;
var a = angular.element('a');
if (wd < 0) {
for (var i = 0; i < a.length; i++) {
var t = a[i].getClientRects()[0].top;
if (t >= 40) break;
}
} else {
for (var i = a.length - 1; i >= 0; i--) {
var t = a[i].getClientRects()[0].top;
if (t < -20) break;
}
}
angular.element('html,body').animate({
scrollTop: a[i].offsetTop
}, 500);
});
}
}
});
关于javascript - 对多个滚动事件执行一次操作并防止滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27465581/