javascript - jQuery: The 'body' element is activating the scroll event twice - Stack Overflow

I've implemented an animation for my photo blog. I still have big problem because the 'body&#

I've implemented an animation for my photo blog. I still have big problem because the 'body' element is activating the animation twice.

I think the problem stems from the $('body').animate. Because I think that when the body is animating, the scroll event would be activated again and thus triggering the event twice.

The problem of my code is scrolling the page up. When I scroll the page upwards. The scrollAnimatePrev will trigger and then $('body') element will animate itself. After the animation the animating variable is set to false. But the $('body') element triggers the scroll event because I guess when I set the scrollTop the scroll event is triggered. So once again currentPos is set to the $(window).scrollTop() then currentPos > previousPos returns true and !animating returns true so it will trigger the scrollAnimate.

Now I want to fix this. How?

    $(function() {
        var record = 0;
        var imgHeight = $(".images").height();
        var offset = $(".images").eq(0).offset();
        var offsetHeight = offset.top;
        var previousPos = $(window).scrollTop();
        var animating = false;
        var state = 0;
        $(window).scroll(function() {
            var currentPos = $(window).scrollTop();
            console.log(currentPos);
            if(currentPos > previousPos && !animating) {
                record++;
                scrollAnimate(record, imgHeight, offsetHeight);
                animating = true;
            } else if (currentPos < previousPos && !animating) {
                record--
                scrollAnimatePrev(record, imgHeight, offsetHeight);
                animating = true;
            }
            previousPos = currentPos;
            console.log(previousPos)
        })


        function scrollAnimate(record, imgHeight, offsetHeight) {
            $('body').animate(
                {scrollTop: (parseInt(offsetHeight) * (record+1)) + (parseInt(imgHeight) * record)},
                1000,
                "easeInOutQuart"                    
            )
            .animate(
                {scrollTop: (parseInt(offsetHeight) * (record)) + (parseInt(imgHeight) * (record))},
                1000,
                "easeOutBounce",
                function() {
                    animating = false;
                }
            )
        }

        function scrollAnimatePrev(record, imgHeight, offsetHeight) {
            $('body').animate(
                {scrollTop: ((parseInt(imgHeight) * record) + (parseInt(offsetHeight) * record)) - offsetHeight},
                1000,
                "easeInOutQuart"
            )
            .animate(
                {scrollTop: ((parseInt(imgHeight) * record) + (parseInt(offsetHeight) * record))},
                1000,
                "easeOutBounce",
                function() {
                    animating = false;
                }
            )
        }
    })

I've implemented an animation for my photo blog. I still have big problem because the 'body' element is activating the animation twice.

I think the problem stems from the $('body').animate. Because I think that when the body is animating, the scroll event would be activated again and thus triggering the event twice.

The problem of my code is scrolling the page up. When I scroll the page upwards. The scrollAnimatePrev will trigger and then $('body') element will animate itself. After the animation the animating variable is set to false. But the $('body') element triggers the scroll event because I guess when I set the scrollTop the scroll event is triggered. So once again currentPos is set to the $(window).scrollTop() then currentPos > previousPos returns true and !animating returns true so it will trigger the scrollAnimate.

Now I want to fix this. How?

    $(function() {
        var record = 0;
        var imgHeight = $(".images").height();
        var offset = $(".images").eq(0).offset();
        var offsetHeight = offset.top;
        var previousPos = $(window).scrollTop();
        var animating = false;
        var state = 0;
        $(window).scroll(function() {
            var currentPos = $(window).scrollTop();
            console.log(currentPos);
            if(currentPos > previousPos && !animating) {
                record++;
                scrollAnimate(record, imgHeight, offsetHeight);
                animating = true;
            } else if (currentPos < previousPos && !animating) {
                record--
                scrollAnimatePrev(record, imgHeight, offsetHeight);
                animating = true;
            }
            previousPos = currentPos;
            console.log(previousPos)
        })


        function scrollAnimate(record, imgHeight, offsetHeight) {
            $('body').animate(
                {scrollTop: (parseInt(offsetHeight) * (record+1)) + (parseInt(imgHeight) * record)},
                1000,
                "easeInOutQuart"                    
            )
            .animate(
                {scrollTop: (parseInt(offsetHeight) * (record)) + (parseInt(imgHeight) * (record))},
                1000,
                "easeOutBounce",
                function() {
                    animating = false;
                }
            )
        }

        function scrollAnimatePrev(record, imgHeight, offsetHeight) {
            $('body').animate(
                {scrollTop: ((parseInt(imgHeight) * record) + (parseInt(offsetHeight) * record)) - offsetHeight},
                1000,
                "easeInOutQuart"
            )
            .animate(
                {scrollTop: ((parseInt(imgHeight) * record) + (parseInt(offsetHeight) * record))},
                1000,
                "easeOutBounce",
                function() {
                    animating = false;
                }
            )
        }
    })
Share Improve this question asked May 5, 2009 at 4:39 Keira NighlyKeira Nighly 15.5k8 gold badges30 silver badges28 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

I think it might be firing that callback twice. I had a similar problem recently.

I had something similiar to

$('#id, #id2').animate({width: '200px'}, 100, function() { doSomethingOnceOnly(); })

It was calling my doSomethingOnceOnly() twice, and I thought it must have been the dual selectors in the $ argument. I simply made it 2 different selectors and it worked fine. So like this

$('#id').animate({width: '200px'}, 100);
$('#id2').animate({width: '200px'}, 100, function() { doSomethingOnceOnly(); );

Using a flag to control the trigger did the trick for me.

var targetOffset = 0;
var allow_trigger = true;
$('html,body').animate({scrollTop: targetOffset}, 'slow', function() {
    if (allow_trigger) {
        allow_trigger = false;
        doSomethingOnlyOnce();
    }
});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744736667a4590790.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信