Scroll Function Firing Multiple Times Instead of Once
Asked Answered
V

2

8

I am trying to create a website that automatically scrolls to each section upon a single scroll action. This means that the code has to check if the page is scrolled up or scrolled down. I believe the code below solves my problem but the scroll action is fired more than once while the page is scrolling. You will see that the first alert in the if statement reaches 5 instead of the desired 1. Any help on the matter would be highly appreciated.

[Note] I am using the velocity.js library to scroll to each section within the container.

var page = $("#content-container");
var home = $("#home-layer-bottom");
var musicians = $("#musicians");
var athletes = $("#athletes");
var politics = $("#politics");
var bio = $("#politics");
var pages = [ home,musicians,athletes,politics,bio ];

var pageCur = 0;


var lastScrollTop = 0;
page.scroll(function(){

var st = $(this).scrollTop();
var pageNex = pageCur + 1;

if (st > lastScrollTop){
    alert(pageNex);
pages[pageNex].velocity("scroll", { container: $("#content-container") });
} else {
   alert(pageCur-1);
pages[pageCur-1].velocity("scroll", { container: $("#content-container") });
}
lastScrollTop = st;
pageCur = pageNex;
});
Vadnee answered 16/1, 2016 at 0:22 Comment(0)
T
14

The scroll event (as well as the resize event) fire multiple times as a user does this. To help this, the best practice is to debounce. However, I've never gotten that to work. Instead, I use a global boolean to check if the function has fired.

var scrolled = false;
page.on('scroll', function(){
    if(!scrolled){
        scrolled = true;
        //do stuff that should take a while...
        scrolled = false;
    };
});
Terrazzo answered 16/1, 2016 at 0:34 Comment(3)
worked perfectly. Just added a setTimeout which runs after 500 milliseconds of the scroll, to make scrolled = false.Kantian
Also had to add a setTimeout since the scroll event queue the requests, so without setTimeout the scroll event will still fire multiple times, just in a synchronous wayScullion
I did the same with a timeout, very simple and cleanAirlia
B
15

This worked for me!

var ScrollDebounce = true;

$('.class').on('scroll', function () {
    if (ScrollDebounce) {
        ScrollDebounce = false;

        //do stuff    

        setTimeout(function () { ScrollDebounce = true; }, 500);
    }
})
Bailiff answered 31/5, 2018 at 16:22 Comment(1)
This actually worked! Thanks. Your name seems familiar, btw. Looks like from usj-r philippinesSuboxide
T
14

The scroll event (as well as the resize event) fire multiple times as a user does this. To help this, the best practice is to debounce. However, I've never gotten that to work. Instead, I use a global boolean to check if the function has fired.

var scrolled = false;
page.on('scroll', function(){
    if(!scrolled){
        scrolled = true;
        //do stuff that should take a while...
        scrolled = false;
    };
});
Terrazzo answered 16/1, 2016 at 0:34 Comment(3)
worked perfectly. Just added a setTimeout which runs after 500 milliseconds of the scroll, to make scrolled = false.Kantian
Also had to add a setTimeout since the scroll event queue the requests, so without setTimeout the scroll event will still fire multiple times, just in a synchronous wayScullion
I did the same with a timeout, very simple and cleanAirlia

© 2022 - 2024 — McMap. All rights reserved.