我有代码使我的窗口从元素滚动到元素。如果我滚动鼠标滚轮一点点它可以正常工作。但如果我滚动得更快,我就会遇到麻烦。
var currentPosition = 1;
angular.element(document).on("mousewheel DOMMouseScroll", function (e) {
e.preventDefault();
e.stopPropagation();
var isUp = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? true : false;
if (isUp) {
if (currentPosition > 0) {
currentPosition--;
setPoinerActive();
$scrollHomePage.scrollTo(vm.myIndex[currentPosition]);
}
}
else {
if (currentPosition < 3) {
currentPosition++;
setPoinerActive();
$scrollHomePage.scrollTo(vm.myIndex[currentPosition]);
}
}
});
回答
function debounce(func, wait, immediate) {
timeout = null;
return function () {
var context = this, args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function () {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
}, wait);
if (immediate && !timeout) {
func.apply(context, args);
}
};
}
答案 0 :(得分:4)
这个问题叫做debouncing,如果你谷歌,你可能会发现它的版本有点不同。当用户向下滚动页面时,Twitter已经注意到它,无限滚动脚本正在加载更多内容。但是当他们足够快地执行它并导致内存泄漏和页面无响应时,他们注意到时间脚本触发了几次。所以他们提出了这个想法,进行了贬低。简单地说,在运行原始事件之前,在函数中添加一个计时器,如果计时器仍然存在,则取消您的事件。所以当你向下滚动而不是触发onscroll事件20次时,超时会触发每隔x毫秒N次。
function debounce(func, wait, immediate) {
var self = this;
self.timeout = null;
return function() {
var context = this, args = arguments;
clearTimeout(self.timeout);
self.timeout = setTimeout(function() {
self.timeout = null;
if (!immediate) {
func.apply(context, args);
}
}, wait);
if (immediate && !self.timeout) {
func.apply(context, args);
}
};
}
然后在原始事件监听器中
angular.element(document).on("mousewheel DOMMouseScroll", debounce(function(e){
e.preventDefault();
e.stopPropagation();
var isUp = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? true : false;
if (isUp) {
if (currentPosition > 0) {
currentPosition--;
setPoinerActive();
$scrollHomePage.scrollTo(vm.myIndex[currentPosition]);
}
}
else {
if (currentPosition < 3) {
currentPosition++;
setPoinerActive();
$scrollHomePage.scrollTo(vm.myIndex[currentPosition]);
}
}
});
}, 300));