简体   繁体   中英

Animate() doesn't work with scrollTop properly

I'm trying to make a script that scrolls the page automatically to the specific element when I scroll my mouse, but for some reason my animation gets repeated and the scroll goes back and forth.

Edit: I would like to point out that this doesn't happen if the page scrolls to the last element on the page, but if it scrolls to the second element it will bounce instantly back to the top.

Here's my jQuery:

$(document).ready(function(){
comp = 0;
current_scroll_position = $(window).scrollTop();
console.log("CURRENT SCROLL POSITION = " +current_scroll_position);

second = $("#second").offset().top;




$(window).scroll(function(scroll_action){

    $('body').on({
        'mousewheel': function(e) {
                e.preventDefault();
                e.stopPropagation();
        }
    });

    if(comp==0){

        console.log("COMP =" +comp);
        comp++;

        new_scroll_position = $(window).scrollTop();

        console.log("YOU SCROLLED, NEW CURRENT POSITION IS :" +new_scroll_position);

        if (new_scroll_position > current_scroll_position){ //scroll going down



            console.log(new_scroll_position +" > "+ current_scroll_position +" GOING DOWN");




                $('body').animate({

                    scrollTop: second
                }, 500,
                function(){ //callback function for completed animation
                    completed_animation_scroll = true;
                    current_scroll_position = $(window).scrollTop();

                    console.log(" ANIMATING ");
                    console.log("CURRENT SCROLL POSITION = " +current_scroll_position);
                    console.log("NEW SCROLL POSITION = " +new_scroll_position);
                    console.log("ANIMATION COMPLETED = " +completed_animation_scroll);
                    console.log(" ******************* ************************ ******************");

                    $('body').unbind('mousewheel');
                    comp = 0;




                 });




        }
        else{

            console.log(new_scroll_position +" > "+ current_scroll_position +" GOING DOWN");

                $('body').animate({

                    scrollTop: 0
                }, 500,
                function(){ //callback function for completed animation
                    completed_animation_scroll = true;
                    current_scroll_position = $(window).scrollTop();

                    console.log(" ANIMATING ");
                    console.log("CURRENT SCROLL POSITION = " +current_scroll_position);
                    console.log("NEW SCROLL POSITION = " +new_scroll_position);
                    console.log("ANIMATION COMPLETED = " +completed_animation_scroll);
                    console.log(" ******************* ************************ ******************");

                    $('body').unbind('mousewheel');
                    comp = 0;




                 });

        }
    }
});
});

Try it: http://jsfiddle.net/81t6w6zv/2/

The problem is in fact that when scrolling animation is done (including success callback), $(window).scroll handler is triggered and works again (because scrolling animation is actually scrolling and comp becomes equal to 0 ).

The easiest way to fix it is to wrap comp = 0 in scrolling animation callback function with setTimeout (I changed type of comp variable to bool):

setTimeout
(
    function()
    {
        comp = false;
    },
    100
);

There are also some "not good things" like binding mousewheel event handler but not unbinding it (if comp not equals to 0 ), so please take a look at updated fiddle to fix such problems in your code.

And full code:

$(document).ready(function()
{
    var comp = false;
    var current_scroll_position = $(window).scrollTop();
    var secondOffsetTop = $("#second").offset().top;  

    $(window).scroll(function()
    {
        if (comp)
        {
            return;
        }
        comp = true;

        $('body').on('mousewheel', function()
        {
            return false;
        });

        var scrollTo = 0;
        if ($(window).scrollTop() > current_scroll_position)
        {
            scrollTo = secondOffsetTop;
        }

        $('body').animate
        (
            {
                scrollTop: scrollTo
            },
            500,
            function()
            {
                current_scroll_position = $(window).scrollTop();
                $('body').off('mousewheel');
                setTimeout
                (
                    function()
                    {
                        comp = false;
                    },
                    100
                );
            }
        );
    });
});

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