7

In my game I have a grid populated with words. To spell the words the user has to click on the letters on the side called "drag". When a letter is clicked it animates into position on the grid.

The problem I am having is that the user can click letters rapidly, which crashes the program. To solve this I want to disable the click events until the animation completes.

In the past I have used a setTimeOut function before but it is not a reliable method as the timing all depends on browser speeds.

Here is the click event:

$('.drag').on('click', function (e) {
    e.preventDefault();
    var target = $('.highlight-problem .drop-box:not(.occupied):first');
    var targetPos = target.parents('td').position();
    console.log(targetPos);
    var currentPos = $(this).offset();
    var b = $(this);
    if (target.length) {
        target.addClass("occupied");
        $(".occupied").parent(".flip-wrapper").addClass("flipped");
        var clonedObject = b.clone()
        if (b.data("letter") == target.parents('td').data("letter")) {
            clonedObject.addClass("right-letter");
            target.addClass('right-letter');
            setTimeout(function () {
                hitSound.play();
            }, 550);
        } else {
            clonedObject.addClass("wrong-letter");
            target.addClass('wrong-letter');
            setTimeout(function () {
                missSound.play();
            }, 550);
        }
        clonedObject.appendTo("table").css({
            position: "absolute",
            top: currentPos.top,
            left: currentPos.left
        }).stop().animate({
            top: targetPos.top,
            left: targetPos.left
        }, "slow", function () {
            $(this).prop('disabled', false).css({
                top: 0,
                left: 0
            }).appendTo(target);
            var spellWord = $('.highlight-problem .drop-box');
            if (!spellWord.filter(':not(.occupied)').length) {
                var wordIsCorrect = 0;
                spellWord.each(function () {
                    if ($(this).parents('td').data("letter") == $(this).find("div").data("letter")) {
                        console.log('letter is: ' + $(this).find("div").data("letter"))
                        wordIsCorrect++;
                    }
                });
Praveen Kumar Purushothaman
  • 154,660
  • 22
  • 177
  • 226
Milo-J
  • 1,098
  • 2
  • 12
  • 25
  • possible duplicate of [jQuery - Disable Click until all chained animations are complete](http://stackoverflow.com/questions/1271828/jquery-disable-click-until-all-chained-animations-are-complete) **API** `.is(':animated')` **or** `$(':animated').length` might help! `:)` – Tats_innit Nov 06 '12 at 09:18
  • how about displaying a loading spinner till the animation completes? – TRR Nov 06 '12 at 09:18
  • create a variable which is set at the end of the animation and wrap the functions which runs on click in an if statement which checks if the variable has been set and only runs if it has. – Sean Lang Nov 06 '12 at 09:18
  • I don't think it is that similar, else I would have used it – Milo-J Nov 06 '12 at 09:33

2 Answers2

8

You can do it in simple 3 steps.

  1. Declare a global variable called animationComplete and set it to false.

    var animationComplete = false;
    
  2. In your .animate({...}); function, toggle the value after the animation is complete.

    .animate({
        top: targetPos.top,
        left: targetPos.left
    }, "slow", function () {
        ...
        animationComplete = true;
    });
    
  3. Check for the completeness using the global variable.

    if (animationComplete)
    {
        // Do something!
    }
    

Full Code

JavaScript

animationComplete = true;
$(document).ready(function(){
    animationComplete = false;
    $(".background").animate({
        height: 50,
        width: 50
    }, 10000, function(){
        animationComplete = true;
    });
    $("button").click(function(){
        if (animationComplete)
            $(".background").animate({
                height: 200,
                width: 200
            }, 10000, function(){
                animationComplete = false;
            });
        else
            alert("Please wait till the animation is complete!");
    });
});

HTML

<div class="background"></div>
<button>Click me!</button>​

CSS

.background {background: red;}

Fiddle: http://jsfiddle.net/KAryP/

Fiddle for your code here: http://jsfiddle.net/smilburn/Dxxmh/94/

Praveen Kumar Purushothaman
  • 154,660
  • 22
  • 177
  • 226
1

Can't test code atm, but checking if the element is not animated within click function should do

if(!$('selector:animated')){


}
Ohgodwhy
  • 44,803
  • 8
  • 64
  • 95