开发者

javascript 'over-clicking' bug

I have a bug in Javascript where I am animating the margin left property of a parent container to show its child divs in a sort of next/previous fashion. Problem is if clicking 'next' at a high frequency the if statement seems to be ignored (i.e. only works if click, wait for animation, then click again) :

 if (marLeft === (-combinedWidth + (regWidth) + "px")) {

                           //roll margin 开发者_开发百科back to 0

                        } 

An example can be seen on jsFiddle - http://jsfiddle.net/ZQg5V/

Any help would be appreciated.


Try the below code which will basically check if the container is being animated just return from the function.

Working demo

                 $next.click(function (e) {
                    e.preventDefault();

                    if($contain.is(":animated")){
                        return;
                    }

                    var marLeft = $contain.css('margin-left'),
                        $this = $(this);

                    if (marLeft === (-combinedWidth + (regWidth) + "px")) {
                        $contain.animate({
                            marginLeft: 0
                        }, function () {
                            $back.fadeOut('fast');
                        });
                    } else {
                        $back.fadeIn(function () {
                            $contain.animate({
                                marginLeft: "-=" + regWidth + "px"
                            });
                        });
                    }
                    if (marLeft > -combinedWidth) {
                        $contain.animate({
                            marginLeft: 0
                        });
                    }
                });


Sometimes is better if you create a function to take care of the animation, instead of writting animation code on every event handler (next, back). Also, users won't have to wait for the animation to finish in order to go the nth page/box.

Maybe this will help you:

if (jQuery) {
    var $next = $(".next"),
        $back = $(".back"),
        $box = $(".box"),
        regWidth = $box.width(),
        $contain = $(".wrap")
        len = $box.length;

    var combinedWidth = regWidth*len;

    $contain.width(combinedWidth);



    var currentBox = 0; // Keeps track of current box

    var goTo = function(n) {
        $contain.animate({
            marginLeft: -n*regWidth
        }, {
            queue: false, // We don't want animations to queue
            duration: 600
        });

        if (n == 0) $back.fadeOut('fast');
        else $back.fadeIn('fast');

        currentBox = n;
    };




    $next.click(function(e) {
        e.preventDefault();
        var go = currentBox + 1;
        if (go >= len) go = 0; // Index based, instead of margin based...
        goTo(go);
    });




    $back.click(function(e) {
        e.preventDefault();
        var go = currentBox - 1;
        if (go <= 0) go = 0; //In case back is pressed while fading...
        goTo(go);
    });

}

Here's an updated version of your jsFiddle: http://jsfiddle.net/victmo/ZQg5V/5/

Cheers!


Use a variable to track if the animation is taking place. Pseudocode:

var animating = false;

function myAnimation() {
  if (animating) return;
  animating = true;     

  $(this).animate({what:'ever'}, function() {
    animating = false;
  });
}

Crude, but it should give you the idea.

Edit: Your current code works fine for me as well, even if I jam out on the button. On firefox.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜