7

I have this function that runs for several seconds with the use of setTimeout. This function is ran when a button is clicked.

function complete() {
    var div = document.getElementById('log');
    setTimeout(function(){ div.innerHTML = div.innerHTML + intro[Math.floor(Math.random() * intro.length)] + "<br>"; }, 500);
    setTimeout(function(){ div.innerHTML = div.innerHTML + second[Math.floor(Math.random() * second.length)] + "<br>"; }, 2560);
    setTimeout(function(){ div.innerHTML = div.innerHTML + third[Math.floor(Math.random() * third.length)] + "<br>"; }, 4860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fourth[Math.floor(Math.random() * fourth.length)] + "<br>"; }, 7860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fifth[Math.floor(Math.random() * fifth.length)] + "<br>"; }, 9640);
}

However, if the user clicks the button multiple times, this function begins to excute multiple times as well. I have tried to prevent this from occuring by using the code below, however, it is not working.

var running;
function complete() {
    if (running == true) { alert('error'); }
    running = true;
    var div = document.getElementById('log');
    setTimeout(function(){ div.innerHTML = div.innerHTML + intro[Math.floor(Math.random() * intro.length)] + "<br>"; }, 500);
    setTimeout(function(){ div.innerHTML = div.innerHTML + second[Math.floor(Math.random() * second.length)] + "<br>"; }, 2560);
    setTimeout(function(){ div.innerHTML = div.innerHTML + third[Math.floor(Math.random() * third.length)] + "<br>"; }, 4860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fourth[Math.floor(Math.random() * fourth.length)] + "<br>"; }, 7860);
    setTimeout(function(){ div.innerHTML = div.innerHTML + fifth[Math.floor(Math.random() * fifth.length)] + "<br>"; }, 9640);
    running = false;
}

What approach should I take, or how can I fix my code so it can accomplish what I am trying to do?

5
  • Store the timeouts and clear them on subsequent clicks. Commented Apr 16, 2014 at 20:18
  • 1
    I believe you'd want to set running = false; at the end of the execution inside your timeouts. You could use a timeout, to run all other timeouts, and at the end of those timeoutes run running = false; may do the trick. So 'false' only gets set once in each loop AFTER all the elements run. You can then run clearTimeout() to stop the loops. Commented Apr 16, 2014 at 20:18
  • You could use clearTimeout to stop them when you first execute complete(). If you want to clear them all at once, refer to this post for an example. Commented Apr 16, 2014 at 20:19
  • A simple solution would be to remove the event listener from the button. How to do it, depends on how have you attached the listener. Can you show, how the listener is attached? Commented Apr 16, 2014 at 20:20
  • 1
    .. you should also return after the alert otherwise the rest of the function will still be executed Commented Apr 16, 2014 at 20:21

3 Answers 3

11

Your running = false; should be inside timeout function, as timeout will execute asyncronically, the running = false; will execute before your timeout ends

A simple example would be

var running = false,
    div = document.getElementById('response'),
    limit = 5,
    current = 0;

$('#trigger').click(function () {
    if (running === true) {
        alert('Error: The cycle was running. Aborting.');
        running = false;
        return false;
    }
    running = true;
    var end = setInterval(function () {
        if (current >= limit || running == false) {
            running = false;
            clearInterval(end);
        }
        div.innerHTML += 'Hello World<br />';
        current++;
    }, 500);

});

JSFiddle Example

Sign up to request clarification or add additional context in comments.

6 Comments

I just explained that to him in my comment on his post. Upvoted ;)
Yeah, saw after I posted answer. I can edit to include your extended explanation if you want
Thank you! However, how can I stop the rest of the function from running after the alert as well?
You can use a return false; after the alert so it exits the function
you can add a if statement in the timeouts to clear them if running was changed to false if( running == false ) clearTimeout();
|
0

Assuming you've used addEventListener to attach the click event to the button, you could remove the listener while timeouts are in progress:

function complete() {
    var div = document.getElementById('log'),
        button = this;
    this.removeEventListener('click', complete);
    setTimeout(function(){...});
                 :
    setTimeout(function(){...});
    // If you later want to make the button clickable again, just uncomment the line below:
    // setTimeout(function () {button.addEventListener('click', complete);}, 10000);
}

Comments

0

for stop running timer you have to clear him

        var stopTimer;

        function someFunction() {
            stopTimer= setTimeout(function(){
                console.log("something done");
            }, 3000);
        }

        function stopFunction() {
            clearTimeout(stopTimer);
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.