views:

38

answers:

2

Hi, I'm using the following code to enable the user to show or hide a photo description (#photoinfo) and a menu (.slidetable) using the up and down arrow keys. If one of these two divs is already open, pressing the opposite arrow closes that div before opening the other.

$(document).unbind('keypress');
$(document).keydown(function(event) {
    switch (event.keyCode) {
    case 38:
        if ($('#photoinfo').is(".open")) {
            closeInfo();
        }
        else if ($('.slidetable').is(".open")) {
            closeSlide2();
            openInfo();
        }
        else {
            openInfo();
        }
        break;
    case 40:
        if ($('.slidetable').is(".open")) {
            closeSlide();
        }
        else if ($('#photoinfo').is(".open")) {
            closeInfo();
            openSlide();
        }
        else {
            openSlide();
        }
        break;
    }
    return false;
});​

It seems to work, only the problem is if two arrows are pressed at the same time, or one after the other, both divs open, overlapping eachother. I'm looking for a way to essentially unbind the keydown function after the first animation initiates, and rebind the keydown function once it finishes. I'm a jquery novice, so maybe this isnt the best way of doing this. What is the easiest way of preventing the other function from firing during the animation?

Thanks

+1  A: 

You can set a boolean (isAnimating) to true before you fire an animation and once it completes set it to false. At the top of keydown just say

if(isAnimating)
{
  event.preventDefault();
  return false;
}

I don't remember the syntax to have a function call at the end of the animation but it's in jQuery's documentation

methodin
$(this).animate({options}, duration, callback);
John Strickler
It's sad I couldn't remember that
methodin
A: 

Sorry, I'm a bit confused. Would the implementation of your answer look something like this, or am I way off?

$(document).unbind('keypress'); 
$(document).keydown(function(event) {
            if(isAnimating)
            {
              event.preventDefault();
              return false;
            }

            switch (event.keyCode) {

                case 38: var isAnimating = true; 

                        if ($('#photoinfo').is(".open")) {
                            closeInfo();

                        }

                        else if ($('.slidetable').is(".open")) {
                            closeSlide2();
                            openInfo();

                        }

                        else {
                            openInfo();


                        } break;


                case 40: var isAnimating = true;
                        if ($('.slidetable').is(".open")) {
                              closeSlide();

                        }

                        else if ($('#photoinfo').is(".open")) {
                            closeInfo();
                            openSlide();

                        }

                        else {
                            openSlide();

                        } break;    

            }
            var isAnimating = false;                                
            return false;
}); 
Thom
Generally but isAnimating should be global. And you'd have to reset it to false inside the animation functions openSlide/closeSlide when those animations complete. The idea is while animating, nothing else can animate, and once the current animation it complete it allows other animations to start. Kind of like a lock.
methodin
I'm trying everything and not getting anywhere. You're saying I would put if(isAnimating) { event.preventDefault(); return false; }in the $(document).ready function in order to making it global? When I do this step by itself, already the page locks up and won't let any click or keypress function work. What should I be doing?
Thom