简体   繁体   中英

scrollTop doesn't seem to be correct

I want to write custom scroll to sections functionality.

When I load the page and scroll down, it should scroll down the height of the window, which is fine.

Then, if scrolling down again, I want to check if the page has scrolled more than window height (which should be, if scrolling down), but it seems to be stuck at where it's at after the first scroll.

So I can get from red to yellow, but not from yellow to green.

var winHeight = window.innerHeight;
$('div').each(function(){
        $(this).css('height', winHeight);
});

function scrollSections() {

        var windowHeight = window.innerHeight;
        var scrollTop = $(window).scrollTop();
        var pos = windowHeight;

        if (scrollTop > windowHeight) {
            pos = windowHeight * 2;
        }

        $('body, html').animate({scrollTop: pos}, 1000, function() {
        });
}

$( window ).on( "scroll", function() {

        scrollSections();

    });

Fiddle: https://jsfiddle.net/zts70yc1/

When you call $('body, html').animate({scrollTop: pos}, ...); , you are triggering scroll events, which will run your handler again, which will start an animation again, based on the current (not final) scroll position, and so on. This multiplies the number of scrolls that happen: this is not what you want.

Instead, before doing anything else in your event handler, check whether an animated scrolling is ongoing, and decide what to do then. For instance, you could just exit the handler in that case, so the animation can continue without interference:

if ($('body, html').is(':animated')) return; // exit when animation ongoing

Also, the formula for setting the target position could be improved, by comparing first the scroll position to the previous scroll position. If higher, then scroll one "page" down, else one "page" up. For that, you should keep pos as a global variable, and do as follows:

var pos = $(window).scrollTop();
function scrollSections() {
        if ($('body, html').is(':animated')) return;
        var windowHeight = window.innerHeight;
        var scrollTop = $(window).scrollTop();
        if (pos == scrollTop) return; // no change
        // depending on scroll direction, go page up, down
        pos += pos < scrollTop ? windowHeight : -windowHeight;
        // round to nearest page boundary
        pos = Math.round(pos / windowHeight) * windowHeight;
        $('body, html').animate({scrollTop: pos}, 1000, function() {
        });
}

These changes have been applied in this fiddle .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM