Paradise
Paradise

Reputation: 470

Prevent User Click

I got a function which displays content based on menu options, each time a user clicks a different option the current active content will fade out and clicked content will display (each div from determined option will display in sequence), my problem is how I could prevent user fast clicking, for example if he decides to click in a different section before the last one ends it will mess up things with the animations the, here is my code.

$(document).ready(function() {
    $("#Default .box").fadeIn(); 
    var $aBox = 0;
    var $menu = "#inner_menu li";
    var $myliID = 0;
    var $myBox = "#Digital_Box .box";
    var $myActiveBox = 0;
    var $myHeight = 0;

    $($menu).click(function() {
        var delay = 0;
        $myliID = $(this).attr("id");
        $myBox = "#" + $myliID + "_Box .box";
          if ($aBox == 1) {
             if ($myActiveBox != $myBox) {
                $($myActiveBox).fadeOut(300);
             }
        $($myBox).delay(300).each(function() 
            {
                $(this).delay(delay).fadeIn(300);
                delay += 500;
              });
            $aBox = 1;
            $myActiveBox = $myBox;
        }
        else
         {
            $("#Default_Box .box").fadeOut(300); 
            $($myBox).delay(300).each(function() 
                {
                    $(this).delay(delay).fadeIn(300);
                    delay += 500;
                });
            $aBox = 1;
            $myActiveBox = $myBox;
        }
        });
});

As you can see I match the li element and it's determined content through their ID, everything works fine but the problem is fast clicking and not letting the other animation finish.

And sorry if my coding sucks, I'm trying to start writing my own "plugins" :P

Upvotes: 0

Views: 1065

Answers (5)

Marc
Marc

Reputation: 11613

Kill the current animations on your menu elements using this:

$("#inner_menu li").stop(true, true);

Then do whatever other animations you want to do.

Upvotes: 0

Brian
Brian

Reputation: 3023

Try giving this a shot. It should set a flag on the parent of the menu items (UL element I assume) so that subsequent clicks on ANY menu item will not do anything until the previous one finishes animating.

$(document).ready(function() {
    $("#Default .box").fadeIn(); 
    var $aBox = 0;
    var $menu = "#inner_menu li";
    var $myliID = 0;
    var $myBox = "#Digital_Box .box";
    var $myActiveBox = 0;
    var $myHeight = 0;

    $($menu).click(function(e) {
        if( $(this).parent().data('animating') ) {
            //already animating
            e.preventDefault(); //stop default click action
            e.stopImmediatePropagation(); //stop click event bubbling
            return; //prevent the animaton from firing below this line
        }
        $(this).parent().data('animating',true);
        var delay = 0;
        $myliID = $(this).attr("id");
        $myBox = "#" + $myliID + "_Box .box";
          if ($aBox == 1) {
             if ($myActiveBox != $myBox) {
                $($myActiveBox).fadeOut(300);
             }
        $($myBox).delay(300).each(function() 
            {
                if( $($myBox).last()[0] == this ) {
                    //this should cause the last animated item to callback and remove the animating flag from the parent (UL item for the menu list)
                    $(this).delay(delay).fadeIn(300,function(){
                        $(this).parent().data('animating',false);
                    });
                } else {
                    $(this).delay(delay).fadeIn(300);
                }
                delay += 500;
              });
            $aBox = 1;
            $myActiveBox = $myBox;
        }
        else
         {
            $("#Default_Box .box").fadeOut(300); 
            $($myBox).delay(300).each(function() 
                {
                    if( $($myBox).last()[0] == this ) {
                        //this should cause the last animated item to callback and remove the animating flag from the parent (UL item for the menu list)
                        $(this).delay(delay).fadeIn(300,function(){
                            $(this).parent().data('animating',false);
                        });
                    } else {
                        $(this).delay(delay).fadeIn(300);
                    }
                    delay += 500;
                });
            $aBox = 1;
            $myActiveBox = $myBox;
        }
        });
});

Upvotes: 0

lifeIsGood
lifeIsGood

Reputation: 1229

To show you what Kolink said -

In $(document).ready(function()

   var isTransitioning = false;

In $($menu).click(function() { wrap everything in an IF

   if (isTransitioning == true) {
         // do nothing
   } else {
         // your code
   }

then add this at start of your code

   isTransitioning = true;
   setTimeout(function() {
     isTransitioning = false;
   }, 2000);

which sets a time limit of 2 second between being able to click items

Upvotes: 1

ShankarSangoli
ShankarSangoli

Reputation: 69905

Use :animated selector to check if the element has not yet finished animation and act accordingly.

E.g.

if(!$(element).is(':animated')){
     //element has finished animation
}

Alternatively you can use stop(true, true) before calling any animation method so that previous animation is completed forcefully.

Upvotes: 0

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324600

Set a variable isTransitioning. Make it true when the user clicks, and false when the animation is complete. If the user clicks when it's true, ignore the click.

Upvotes: 0

Related Questions