-1

Possible Duplicate:
How to pause a setTimeout call ?

I have a function that gets called on page load which starts off a repeating function:

        setTimeout(function () {
            repeat();
        }, 8000)

This function calls repeat() every 8 seconds, inside this function I have a bit of ajax which updates a counter on the page. Clicking on the counter gives the user a drop down menu with a number of messages. The counter value equals the number of messages the user has. Kind of like Facebook notifications.

When clicking the drop down menu Im using jQuery to hide and show it:

  $('#messages').click(function () {
        $('#messagesDropDown').slideDown();
    })
    .mouseleave(function () {
        $('#messagesDropDown').slideUp();
    });

When the #messagesDropDown is visible I want to stop the repeat() function, to prevent the list of messages from updating while Im viewing the current ones.

On .mouseleave I want to start the repeat() function again.

Anyone have any ideas how I can 'STOP' a repeating function In the .click function and start it again on .mouseleave ?

Community
  • 1
  • 1
CLiown
  • 13,665
  • 48
  • 124
  • 205

2 Answers2

2

setTimeout returns a ID of the timeout. You can store that value, and then use clearTimeout to stop the timeout when you want.

var timeout;
$('#messages').click(function () {
        $('#messagesDropDown').slideDown(function () {
            clearTimeout(timeout); // Cancel the timeout when the slideDown has completed.
        });
    })
    .mouseleave(function () {
        $('#messagesDropDown').slideUp();
        clearTimeout(timeout); // Cancel incase it's still running (you can also set `timeout` to undefined when you cancel with clearTimeout, and apply some logic here (`if (timeout == undefined)` so you can leave it running rather than restarting it)
        timeout = setTimeout(repeat, 8000); // Store the ID of the timeout
    });

setTimeout will not set a recurring event; it will only fire once (like a delayed event). Look at setInterval (and clearInterval) instead.

Matt
  • 74,352
  • 26
  • 153
  • 180
1

You said that this code starts a repeating function:

setTimeout(function () {
    repeat();
}, 8000)

Since setTimeout doesn't repeat, I assume that the repeat function itself fires off another setTimeout to call itself again after it runs (chained setTimeout calls).

If so, you have two options:

  1. Have a control variable telling repeat whether to do its work or not. A simple boolean will do. Set the boolean when you want repeat to skip its work, and have repeat check it. This is the dead simple answer.

  2. Have control functions for repeat, like so:

    var repeatHandle = 0;
    function startRepeat() {
        if (!repeatHandle) {
            repeatHandle = setTimeout(repeatTick, 8000);
        }
    }
    function repeatTick() {
        repeatHandle = 0;
        repeat();
    }
    function stopRepeat() {
        if (repeatHandle) {
            clearTimeout(repeatHandle);
            repeatHandle = 0;
        }
    }
    

    ...and then use them to control the repeats. Be sure to modify repeat to call startRepeat to schedule its next call rather than calling setTimeout directly.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875