Home Ask Login Register

Developers Planet

Your answer is one click away!

Andrew Denaro February 2016

Animated Scroll on Page Up/Down Event

I am trying to build a website that automatically scrolls to each section when the user scrolls the page up or down. I have been trying to solve this problem for weeks and would appreciate any help on the matter. I believe the problem is since the event handler is a scroll event which fires a scroll function this causes more than one scroll to occur. I have read many articles discussing this topic and the solution seems to be adding a setInterval or setTimeout function, but I have tried both and still no results.

var page = $("#page_container");
var home = $("#home");
var musicians = $("#musicians");
var athletes = $("#athletes");
var politics = $("#politics");
var bio = $("#bio");
var pages = [home, musicians, athletes, politics, bio];
var scrolled = false;
var pageCur = 0;
var lastScrollTop = 0;

page.scroll(function () {
    scrolled = true;
});

var scrollTimeout = setInterval(function () {
    if (scrolled == true) {
        pageScroll();
    }
    else {
        clearTimeout(scrollTimeout);
    }
}, 3000);

function pageScroll() {
    if (scrolled == true) {
        scrolled = false;
        var st = page.scrollTop();
        var pageNex = pageCur + 1;

        if (st > lastScrollTop) {
            alert(pageNex);
            pages[pageNex].velocity("scroll", {container: $("#page_container")});
        } else {
            alert(pageCur - 1);
            pages[pageCur - 1].velocity("scroll", {container: $("#page_container")});
        }
        lastScrollTop = st;
        pageCur = pageNex;
        alert("1");
        clearTimeout(scrollTimeout);

    }
}

Answers


Evochrome February 2016

Indeed set a timeout :) I think you were close to the solution. Try this little code:

page.on('mousewheel', function (e) {
          if(Timeout)  
            return //if Timout == TRUE, then stop this function
          Timeout = true //if Timout == FALSE, set TRUE and then execute
          pageScroll(e) //scrollfunction to be called, Scrolling all the way!! YEAAH
          setTimeout(function(){Timeout = false},250)//Set Timeout to False after 0.25s
        });

function pageScroll(e) {
        var st = page.scrollTop();
        var pageNex = pageCur + 1;
    if (st > lastScrollTop) {
        alert(pageNex);
        pages[pageNex].velocity("scroll", {container: $("#page_container")});
    } else {
        alert(pageCur - 1);
        pages[pageCur - 1].velocity("scroll", {container: $("#page_container")});
    }
    lastScrollTop = st;
    pageCur = pageNex;
    alert("1");
    e.preventDefault();
}

Check This fiddle for a working example!

Hope it helped :)

EDIT: A working fiddle added!


chiliNUT February 2016

I notice you are using velocity, but I'm not familiar with that plugin. This is a pure jquery implementation that does not use setInterval/setTimeout:

    var page = $("#page_container");
    var home = $("#home");
    var musicians = $("#musicians");
    var athletes = $("#athletes");
    var politics = $("#politics");
    var bio = $("#bio");
    var pages = [home, musicians, athletes, politics, bio];
    var positions = [];
    $.each(pages, function (k, page) {
        positions.push(parseInt(page.position().top));
    });
    //make sure we dont try to scoll while scrolling
    var scrolling=false;
    $(page).on("mousewheel DOMMouseScroll", function (event) {
        event.preventDefault();
        if (scrolling===true) {
            return false;
        }
        scrolling=true;
        var scrollTop = $(window).scrollTop();
        var scrollTo = -1;
        if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
// scroll up, find the HIGHEST position on the page LOWER than our scroll
            $.each(positions, function (k, position) {
                if (position < scrollTop) {
                    scrollTo = position;
                }
            });
        }
        else {
            // scroll down, find the LOWEST position HIGHER than our scroll
//since the list is sorted, stop on the first one
            $.each(positions, function (k, position) {
                if (position > scrollTop) {
                    scrollTo = position;
                    return false;
                }
            });
        }
        if (scrollTo > -1) {
            //dont scroll if were already at the top and scrolling up
            //or at the bottom and scrolling down
            $('html, body').animate({scrollTop: scrollTo + 'px'}, function(){
                //allow scrolling again
                scrolling=false;
            });
        } else {
            scrolling=false;
      

Post Status

Asked in February 2016
Viewed 1,272 times
Voted 13
Answered 2 times

Search




Leave an answer


Quote of the day: live life