kouk
kouk

Reputation: 81

jQuery - avoid listening to arrow keys while function is executing

SCENARIO

I have developed a function with jQuery which listens to the user's keyboard (based on the keydown() method).

I analyze the user's input with evt.keyCode, and if the down or up arrow keys are pressed, then an animated smooth scroll is executed.

PROBLEM

The animation lasts 1 second.

I don't want the function to listen to any input while the execution of the animations lasts.

That is, if the user presses several times the down and up arrow keys in 1 second, only the first one should be taken into account, and until the execution time (1 second) is over, the rest of the keystrokes should be discarded.

How can I accomplish this?

JS CODE

$(function () { 

  $(document).keydown(function (evt) {

    if (evt.keyCode == 40) {

                $('html,body').animate({scrollTop: 50}, 1000);

    } else if (evt.keyCode == 38) {

                $('html,body').animate({scrollTop: 0}, 1000);

    }

    return false;

  });

});

Upvotes: 2

Views: 47

Answers (3)

BCDeWitt
BCDeWitt

Reputation: 4773

The .animate() method can call a function when it is completed. You could remove the event handler using .off(), then re-add it when the animation is complete.

$(function () { 

    function attachOnKeydown() {
        $(document).on('keydown', onKeydown);
    }

    function onKeydown(evt) {

        // Detach onKeyDown()
        $(document).off('keydown', onKeydown);

        if (evt.keyCode == 40) {

            $('html,body').animate({scrollTop: 50}, 1000, attachOnKeydown);

        } else if (evt.keyCode == 38) {

            $('html,body').animate({scrollTop: 0}, 1000, attachOnKeydown);

        }

        return false;

    }

    attachOnKeydown();

});

Upvotes: 0

koga73
koga73

Reputation: 1022

Check to see if you're already animating using .is(":animated")

$(function () { 
  $(document).keydown(function (evt) {
    if ($('html,body').is(":animated")){
        return false;
    }
    if (evt.keyCode == 40) {
                $('html,body').animate({scrollTop: 50}, 1000);
    } else if (evt.keyCode == 38) {
                $('html,body').animate({scrollTop: 0}, 1000);
    }
    return false;
  });
});

Upvotes: 1

tymeJV
tymeJV

Reputation: 104775

Set a flag when a key is pressed, reset the flag at the end of the animation:

var isAnimating = false;
$(document).keydown(function (evt) {
    if (isAnimating == false) {
        isAnimating = true;
    } else {
        return;
    }
    if (evt.keyCode == 40) {

            $('html,body').animate({scrollTop: 50}, 1000, function() {
                isAnimating = false;
            });

    } else if (evt.keyCode == 38) {

            $('html,body').animate({scrollTop: 0}, 1000, function() {
                isAnimating = false;
            });

    }

    return false;
});

Upvotes: 3

Related Questions