user759235
user759235

Reputation: 2207

Stop a loop with an click event jQuery

I am looking for a way to stop a loop with a click event(sort of panic button). If you click the button it should stop immediately.

// basic idea

$.each(someArray, function(index, value){
    setTimeout(function(){
          console.log(index);
     },5000*index);
});


$('#panic-button').click(function(){
    //the code that should stop the looping
}):

Upvotes: 0

Views: 6407

Answers (4)

Musa
Musa

Reputation: 97672

If you want to have a loop in the background that you can terminate you'll have to simulate it because js is essentially single threaded, and your loop will block until it finishes then you'll be able to click a button.

Here is an example, it uses settimeout to simulate a loop that can be cancelled by a click

FIDDLE

Upvotes: 3

Cosmin Atanasiu
Cosmin Atanasiu

Reputation: 2654

Create the function return value outside of the $.each() and use a flag variable to determine whether or not the button was clicked. I generally declare the global functions and variables using "window."

var panicButtonClicked = false;  
window.panicButtonClicked = panicButtonClicked;
var timeouts = [];
window.timeouts = timeouts;

$.each(someArray, function(index, value){
    if( !panicButtonClicked )
    {
         timeouts.push( setTimeout(function(){
          console.log(index);
         }, 5000*index) );
    }
});

$('#panic-button').click(function(){
    //the code that should stop the looping
    panicButtonClicked = true;
    $.each(timeouts, function (_, id) {
        clearTimeout(id);
    });
}); 

I've included the for loop given by Jonathan Lonowski in my edit. The idea is similar, except that you'd need an extra variable to prevent your initial loop from executing. Does this solve your problem ?

Upvotes: 1

Jonathan Lonowski
Jonathan Lonowski

Reputation: 123443

You can't interrupt the $.each loop with a click handler once the loop has started. JavaScript execution is single-threaded, so the click handler will at best be queued up for the next time the thread is free -- after the loop has finished.

However, as timers are executed asynchronously, you can cancel them by keeping and clearing each of their IDs:

var timeouts = [];

$.each(someArray, function(index, value){
    timeouts.push(setTimeout(function(){
          console.log(index);
     },5000*index));
});


$('#panic-button').click(function(){
    $.each(timeouts, function (_, id) {
       clearTimeout(id);
    });

    timeouts = [];
}):

Upvotes: 3

Anriëtte Myburgh
Anriëtte Myburgh

Reputation: 13517

You're answer is very simple:

Add var $theTimeout = in front of setTimeout and clear it in your click handler: clearTimeout($theTimeout).

http://www.w3schools.com/js/js_timing.asp

Upvotes: 0

Related Questions