我如何知道何时停止使用Javascript进行滚动?
答案 0 :(得分:58)
您可以为scroll
事件添加事件处理程序并启动超时。类似的东西:
var timer = null;
$(window).addEventListener('scroll', function() {
if(timer !== null) {
clearTimeout(timer);
}
timer = setTimeout(function() {
// do something
}, 150);
}, false);
这将开始超时并等待150ms。如果在此期间发生新的scroll
事件,则中止计时器并创建新计时器。如果不是,则执行该功能。你可能需要调整时间。
另请注意,IE使用不同的方式来附加事件侦听器,这应该给出一个很好的介绍:quirksmode - Advanced event registration models
答案 1 :(得分:26)
没有“停止滚动”事件。如果要在用户完成滚动后执行某些操作,可以在“OnScroll”事件中设置计时器。如果您再次触发“OnScroll”事件,则重置计时器。当计时器最终触发时,您可以假设滚动已停止。我认为500毫秒是一个很好的开始时间。
以下是一些适用于IE和Chrome的示例代码:
<html>
<body onscroll="bodyScroll();">
<script language="javascript">
var scrollTimer = -1;
function bodyScroll() {
document.body.style.backgroundColor = "white";
if (scrollTimer != -1)
clearTimeout(scrollTimer);
scrollTimer = window.setTimeout("scrollFinished()", 500);
}
function scrollFinished() {
document.body.style.backgroundColor = "red";
}
</script>
<div style="height:2000px;">
Scroll the page down. The page will turn red when the scrolling has finished.
</div>
</body>
</html>
答案 2 :(得分:3)
(function( $ ) {
$(function() {
var $output = $( "#output" ),
scrolling = "<span id='scrolling'>Scrolling</span>",
stopped = "<span id='stopped'>Stopped</span>";
$( window ).scroll(function() {
$output.html( scrolling );
clearTimeout( $.data( this, "scrollCheck" ) );
$.data( this, "scrollCheck", setTimeout(function() {
$output.html( stopped );
}, 250) );
});
});
})( jQuery );
=======&GT;&GT;&GT;&GT; Working Example here
答案 3 :(得分:2)
我做了类似的事情:
var scrollEvents = (function(document, $){
var d = {
scrolling: false,
scrollDirection : 'none',
scrollTop: 0,
eventRegister: {
scroll: [],
scrollToTop: [],
scrollToBottom: [],
scrollStarted: [],
scrollStopped: [],
scrollToTopStarted: [],
scrollToBottomStarted: []
},
getScrollTop: function(){
return d.scrollTop;
},
setScrollTop: function(y){
d.scrollTop = y;
},
isScrolling: function(){
return d.scrolling;
},
setScrolling: function(bool){
var oldVal = d.isScrolling();
d.scrolling = bool;
if(bool){
d.executeCallbacks('scroll');
if(oldVal !== bool){
d.executeCallbacks('scrollStarted');
}
}else{
d.executeCallbacks('scrollStopped');
}
},
getScrollDirection : function(){
return d.scrollDirection;
},
setScrollDirection : function(direction){
var oldDirection = d.getScrollDirection();
d.scrollDirection = direction;
if(direction === 'UP'){
d.executeCallbacks('scrollToTop');
if(direction !== oldDirection){
d.executeCallbacks('scrollToTopStarted');
}
}else if(direction === 'DOWN'){
d.executeCallbacks('scrollToBottom');
if(direction !== oldDirection){
d.executeCallbacks('scrollToBottomStarted');
}
}
},
init : function(){
d.setScrollTop($(document).scrollTop());
var timer = null;
$(window).scroll(function(){
d.setScrolling(true);
var x = d.getScrollTop();
setTimeout(function(){
var y = $(document).scrollTop();
d.setScrollTop(y);
if(x > y){
d.setScrollDirection('UP');
}else{
d.setScrollDirection('DOWN');
}
}, 100);
if(timer !== 'undefined' && timer !== null){
clearTimeout(timer);
}
timer = setTimeout(function(){
d.setScrolling(false);
d.setScrollDirection('NONE');
}, 200);
});
},
registerEvents : function(eventName, callback){
if(typeof eventName !== 'undefined' && typeof callback === 'function' && typeof d.eventRegister[eventName] !== 'undefined'){
d.eventRegister[eventName].push(callback);
}
},
executeCallbacks: function(eventName){
var callabacks = d.eventRegister[eventName];
for(var k in callabacks){
if(callabacks.hasOwnProperty(k)){
callabacks[k](d.getScrollTop());
}
}
}
};
return d;
})(document, $);
代码可在此处获取:documentScrollEvents
答案 4 :(得分:1)
答案 5 :(得分:1)
我正在尝试添加一个display:block属性,用于之前隐藏在滚动事件上的社交图标,然后在2秒后再次隐藏。但是
在第一次滚动自动启动并且没有重置超时想法之后,我也遇到了与我的超时代码相同的问题。因为它没有适当的重置功能。但是在我看到David关于这个问题的想法之后,我能够重置超时,即使有人在实际完成前一次超时之前再次滚动。
下面显示的问题代码
$(window).scroll(function(){ setTimeout(function(){ $('.fixed-class').slideUp('slow'); },2000); });
如果在2s之前发生下一次滚动
,则使用重置计时器编辑和使用代码
var timer=null; $(window).scroll(function(){ $('.fixed-class').css("display", "block"); if(timer !== null) { clearTimeout(timer);
} timer=setTimeout(function(){ $('.fixed-class').slideUp('slow'); },2000);});
我的工作代码将触发一个名为“fixed-class”的隐藏分区,以便在每个滚动条上显示。从最新滚动开始,计时器将计数2秒,然后再次将显示从块更改为隐藏。
答案 6 :(得分:1)
这是我在名为 scroll-into-view-if-needed
的存储库中找到的更现代的基于 Promise 的解决方案不是在 addEventListener
事件上使用 scroll
,而是使用 requestAnimationFrame
来观察没有移动的帧,并在有 20 帧没有移动时解析。
function waitForScrollEnd () {
let last_changed_frame = 0
let last_x = window.scrollX
let last_y = window.scrollY
return new Promise( resolve => {
function tick(frames) {
// We requestAnimationFrame either for 500 frames or until 20 frames with
// no change have been observed.
if (frames >= 500 || frames - last_changed_frame > 20) {
resolve()
} else {
if (window.scrollX != last_x || window.scrollY != last_y) {
last_changed_frame = frames
last_x = window.scrollX
last_y = window.scrollY
}
requestAnimationFrame(tick.bind(null, frames + 1))
}
}
tick(0)
})
}
使用 async/await 然后
await waitForScrollEnd()
waitForScrollEnd().then(() => { /* Do things */ })