DavidR
DavidR

Reputation: 5388

Javascript: do an action after user is done scrolling

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

Answers (6)

muskatnuss
muskatnuss

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

lenooh
lenooh

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

Šime Vidas
Šime Vidas

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

Alan Mabry
Alan Mabry

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

Felix Kling
Felix Kling

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

Macy Abbey
Macy Abbey

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

Related Questions