Phatyh T.
Phatyh T.

Reputation: 45

I have issue with setTimeout/clearTimeout

I have following js

document.addEventListener("DOMContentLoaded", function() {
  document.querySelector("#pageRedirect").addEventListener("change", changeHandler);
});

function changeHandler() {
  var timer;
  if (pageRedirect.checked) {
    timer = setTimeout(function() {
      window.location.href = 'http://www.google.com';
    }, 3000);

    console.log(pageRedirect.checked);
  } else {
    //dont redirect
    clearTimeout(timer);

    console.log(pageRedirect.checked);
  }
}
<input type="checkbox" id="pageRedirect" name="pageRedirect" />

I dont redirect when checkbox uncheck but it is. Where's my fault ?

Thanks.

Upvotes: 0

Views: 127

Answers (2)

JSelser
JSelser

Reputation: 3630

The issue is that the timer variable is redeclared every time the function executes, so even having closures, the viariable doesn't hold the timer.

You could store the timer somewhere else, like in the node. Notice in the following snippet I store the timer in this.timer

document.addEventListener("DOMContentLoaded", function () {
    document.querySelector("#pageRedirect").addEventListener("change", changeHandler);
});

function changeHandler(){
    if(pageRedirect.checked){
        this.timer = setTimeout(function(){
            document.getElementById('output').innerHTML = "done";
        }, 3000);
    } else {
        //dont redirect
        clearTimeout(this.timer);
    }
}
<input type="checkbox" id="pageRedirect" name="pageRedirect"/>

<div id="output"></div>

Upvotes: 1

James Thorpe
James Thorpe

Reputation: 32192

The issue is the location of your variable declaration for the timer ID. It's inside your function, so when you attempt to clear it, it's not got the ID you assigned in the setTimeout. You need to move the declaration outside of your function so it can keep the handle of the timer between invocations:

var timer;
function changeHandler(){
    // etc

This is compounded by the spec for clearTimeout which says:

If handle does not identify an entry in the list of active timeouts of the WindowTimers object on which the method was invoked, the method does nothing.

I.E. it will silently ignore any invalid timer handles, which in your case would be undefined.

Upvotes: 3

Related Questions