Talon
Talon

Reputation: 4995

How to clear a javascript timeout thats set within a function

I have a recursive type function in Javascript that runs like this:

function loadThumb(thumb) {
    rotate=setTimeout(function() {
        loadThumb(next);
    }, delay);
}

Note: I've simplified the function to make it easier to read.

I have "a" tags called like this

<a href="#" onclick="loadThumb(3); clearTimeout(rotate);">Load thumb 3</a>

However, they don't clearout the timer, the timer continues to cycle through the function irregardless of the clearTimeout() being called.

Any ideas why? I think it might have something to do with a scope problem or something like that.

Upvotes: 9

Views: 15626

Answers (6)

Krasimir
Krasimir

Reputation: 13529

I'm not sure what exactly you are doing, because as far as I can see you didn't post all the code, but this looks better for me:

function loadThumb(thumb) {

    return setTimeout(function() {
        loadThumb(next);
    }, delay);

}

and then:

<a href="#" onclick="clearTimeout(loadThumb(3));">Load thumb 3</a>

Upvotes: 0

If you have to manage multiple timeouts, you can use an object in the global scope and some custom methods to create and remove your timeouts. To access the methods you can either put the calls in the onclick handler of your links (like in the example), or use a library like jQuery to bind them.

<script type="text/javascript">
    var timeouts = timeouts || {};

    function createTimeout(name, milliseconds, callback) {
        timeouts.name = setTimeout(callback, milliseconds);
    }

    function removeTimeout(name) {
        if (typeof(timeouts.name) !== undefined) {
            clearTimeout(timeouts.name);
            timeouts.name = undefined;
        }
    }

    createTimeout('foo', 5000, function() {
        alert('timeout')
    });
</script>

i have also posted an example on jsFiddle http://jsfiddle.net/AGpzs/

Upvotes: 0

mplungjan
mplungjan

Reputation: 177786

Return false on the link

Since you are not using var rotate, it should not be a scoping issue since rotate would be in the window scope. Can you show the complete code?

It is considered poor coding to inline the script - you should attach the event handler onload of the page

Also you should not have the setTimeout inside a function that might be called for one image

Try this:

var rotate,next=1;
function loadThumb(thumb) {
  if (thumb) ... use thumb
  else ... use next
}

function slide() {
    rotate=setInterval(function() {
        loadThumb();
        next++; 
        if (next>=images.length) next=0;
    }, delay);
}

window.onload=function() {
  var links = document.getElementsByTagName("a");
  if (links[i].className==="thumbLink") {
    links[i].onclick=function() {
      var idx = this.id.replace("link","");
      loadThumb(idx);
      clearInterval(rotate);
      return false;
    }
  }
  document.getElementById("start").onclick=function() {
    slide();
    return false;
  }
  document.getElementById("stop").onclick=function() {
    clearInterval(rotate);
    return false;
  }
  slide();
}

assuming

<a href="#" id="start">Start</a>
<a href="#" id="stop">Stop</a>

<a href="#" id="link0" class="thumbLink">Show 1</a>
<a href="#" id="link1" class="thumbLink">Show 2</a>
<a href="#" id="link2" class="thumbLink">Show 3</a>

Upvotes: 0

Hemant Metalia
Hemant Metalia

Reputation: 30648

it may be the issue of scope so make rotate as global variable and call clearTimeout(rotate);

refer clearTimeout() example

Upvotes: 2

benesch
benesch

Reputation: 5269

Yeah, you need to make rotate a global variable. Simply declare it outside the function like so:

var rotate;
var delay = 1000;

function loadThumb(thumb) {
    alert("loading thumb: " + thumb);
    rotate = setTimeout(function() {
        loadThumb(thumb + 1);
    }, delay);
}

Also, you need to make sure you clear the timeout before you call loadThumb. Otherwise you'll clear the timer you just started.

<a href="#" onclick="clearTimeout(rotate); loadThumb(3);">Load thumb 3</a>

fiddle: http://jsfiddle.net/63FUD/

Upvotes: 14

Mutation Person
Mutation Person

Reputation: 30498

It may be a scoping issue if you are not declaring rotate externally.

Try this:

var rotate = 0;
function loadThumb(thumb) {

    rotate=setTimeout(function() {
        loadThumb(next);
    }, delay);

}

Upvotes: 1

Related Questions