Rache Riveto
Rache Riveto

Reputation: 51

clearTimeout() is not working properly

Here is a JSFiddle example of the problem.

When I click the button everything fades as expected and returns in 3 seconds or until cliked. However, if I do not wait the 3 seconds but click it early and then quickly click the button it returns in less than 3 seconds.

EDIT: a better explanation of the problem: In the JSFiddle, click the green button, click the open space to stop the fade, and then click the green button again (this all has to be done quickly). The elements fade back in way too quickly.

Thanks Katana314

var waiting;

function startNext() {
  $(document).off('click');
  window.clearTimeout(waiting);
  $('#correctT, #correctP').fadeOut('fast', function() {
    $('#button1, #button2, #button3, #button4, #title, #image, #ame').fadeIn('slow');


  })

}
$('#button1, #button2, #button3, #button4').click(function(e) {


  $('#button1, #button2, #button3, #button4, #title, #image, #ame').fadeOut('fast', function() {


    $('#button1, #button2, #button3, #button4, #title, #image, #ame').hide();
    $('#correctT, #correctP').fadeIn('fast');

    $(document).click(startNext);

    waiting = setTimeout(startNext, 2500);
  });
});

Upvotes: 0

Views: 655

Answers (2)

Robert Parham
Robert Parham

Reputation: 704

https://jsfiddle.net/1dmjvon3/3/

take care of your timeout ids...

if(waiting!==null){
    window.clearTimeout(waiting);
    waiting = null;
}

also

if(waiting===null) waiting = setTimeout(startNext, 2500);

A more appropriate solution is to assign a class name to each of the elements in your selector and use the classname as the selector so the function doesn't fire seven times.

Here's another fiddle: https://jsfiddle.net/1dmjvon3/

Upvotes: -1

Matt Burland
Matt Burland

Reputation: 45155

The root of your problem is here:

$('#button1, #button2, #button3, #button4, #title, #image, #ame').fadeOut('fast', function() {


    $('#button1, #button2, #button3, #button4, #title, #image, #ame').hide();
    $('#correctT, #correctP').fadeIn('fast');

    $(document).click(startNext);

    waiting = setTimeout(startNext, 2500);
    console.log("started timer:" + waiting );
});

If you run this and look at your console what do you see? You see that you are starting not one, but 7 timers. Your fadeOut handler will be called for each of your elements. So you start 7 timers, but waiting only has the id of the last timer started. So the other 6 are still running. Robert's answer above avoids that problem by not starting another timer if one is already set and that works. A cleaner solution would be to wait for all the animations to be done. For example, see here:

jQuery wait till all page animations are done

So something like this ought to work:

$('#button1, #button2, #button3, #button4, #title, #image, #ame').fadeOut('fast').promise().done(function() {


    $('#button1, #button2, #button3, #button4, #title, #image, #ame').hide();
    $('#correctT, #correctP').fadeIn('fast');

    $(document).click(startNext);

    waiting = setTimeout(startNext, 2500);
    console.log("started timer:" + waiting);
});

Upvotes: 2

Related Questions