Reputation: 5388
I'm trying to figure out a way to do this. I have a list of boxes, each about 150px
high. I am using javascript (and jquery) and want that, after a user scrolls down a page, the page will auto scroll so that the boxes line up with the rest of the page (that is to say, if the user scrolls and the y position of the page is not divisible by 150, it will scroll to that nearest point).
Now, I at the moment, I know I can activate an event using the .scroll()
jquery event, and I can make it move to a certain point using .scrollTop()
. But every pixel the user moves the scroll bar activates the whole function. So is there a way to delay the function from firing until the user hasn't scrolled, and if they should begin to scroll again, the function will halt?
Upvotes: 19
Views: 32213
Reputation: 33
A solution without jQuery would be using the scrollend event. Here is the MDN documentation.
A code example from the documentation is:
element.addEventListener("scrollend", (event) => {});
Please note that as of October 2024 Safari doesn't support this event.
Upvotes: 0
Reputation: 10682
This is basically the same as Šime Vidas' answer, but less complex:
var scrollTimeout = null;
$(window).scroll(function(){
if (scrollTimeout) clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(function(){yourFunctionGoesHere()},500);
});
500 is the delay. Should be ok for mouse scroll.
Upvotes: 12
Reputation: 185923
The code:
var scrollTimeout = null;
var scrollendDelay = 500; // ms
$(window).scroll(function() {
if ( scrollTimeout === null ) {
scrollbeginHandler();
} else {
clearTimeout( scrollTimeout );
}
scrollTimeout = setTimeout( scrollendHandler, scrollendDelay );
});
function scrollbeginHandler() {
// this code executes on "scrollbegin"
document.body.style.backgroundColor = "yellow";
}
function scrollendHandler() {
// this code executes on "scrollend"
document.body.style.backgroundColor = "gray";
scrollTimeout = null;
}
Upvotes: 6
Reputation: 17
This would be a scenario, where vanilla JavaScript would be useful.
var yourFunction = function(){
// do something computationally expensive
}
$(window).scroll(function(){
yfTime=setTimeout("yourFunction()",250);
});
Upvotes: -2
Reputation: 816462
As you are already using jQuery, have a look at Ben Alman's doTimeout plugin which already handles the debouncing of methods (which is what you are after).
Example shamelessly stolen from his website:
$(window).scroll(function(){
$.doTimeout( 'scroll', 250, function(){
// do something computationally expensive
});
});
Upvotes: 22
Reputation: 3887
Sure, in the event handler for the scroll event, fire off a setTimeout for 100 or 200 milliseconds later. Have that setTimeout function you set inside of the scroll event handler do the positioning logic you mention above. Also have the scroll event handler clear any timeouts set by itself. This way, the last time the scroll event fires, the setTimeout function will get to complete as the scroll event has not cleared it.
Upvotes: 6