Reputation: 5985
My main question is: Does clearTimeout() stop the timer AND not execute the function within the timer? OR does it just clear the timeout and immediately execute the function?
Here's my example
$('input').keyup(function(){
var thisClass = $(this).attr('class').split(" ");
var thisValue = $(this).val();
var thisError = $(this).parent().siblings('.error');
var thisTimeout;
if(thisClass[1] == "letters"){
if(thisValue.length <= 1){
thisTimeout = setTimeout(function(){
thisError.html("You must have at least 2 characters");
thisError.show();
}, 800);
} else {
clearTimeout(thisTimeout);
thisError.hide();
thisError.html("");
}
}
});
This is part of a code checks to see if an input box has at least 2 characters in it. currently, This code executes the timeout well after 800 miliseconds if it has 2 or less characters. When the input box has more than 2 characters, if I'm typing fast enough, the error box still shows up when I finish typing. I can clear the error by typing one more character, but if I were to type my name quickly, The error shows up when I'm done typing.
I also have this piece of code:
$('input').keydown(function(){
clearTimeout(thisTimeout);
thisError.hide();
});
Hoping that it would clear the error if I kept typing Thoughts?
Upvotes: 1
Views: 2167
Reputation: 4055
In your first question you asked:
Does clearTimeout() stop the timer AND not execute the function within the timer? OR does it just clear the timeout and immediately execute the function?
The answer is the first option – clearTimeout
stops the timer and does not execute the timer callback.
The problem in your code question is because thisTimeout
is declared inside the keyup
function. The keydown
function doesn't have a reference to thisTimeout
.
You should move it to a shared scope instead:
var thisTimeout;
$('input').keyup(function(){
var thisClass = $(this).attr('class').split(" ");
var thisValue = $(this).val();
var thisError = $(this).parent().siblings('.error');
if(thisClass[1] == "letters"){
if(thisValue.length <= 1){
thisTimeout = setTimeout(function(){
thisError.html("You must have at least 2 characters");
thisError.show();
}, 800);
} else {
clearTimeout(thisTimeout);
thisError.hide();
thisError.html("");
}
}
});
$('input').keydown(function(){
clearTimeout(thisTimeout);
thisError.hide();
});
});
Upvotes: 1
Reputation: 707436
You have to move thisTimeout
to a higher scope so its value is preserved and you have to clear it before you overwrite the previous value:
var thisTimeout;
$('input').keyup(function(){
var thisClass = $(this).attr('class').split(" ");
var thisValue = $(this).val();
var thisError = $(this).parent().siblings('.error');
if(thisClass[1] == "letters"){
if(thisValue.length <= 1){
clearTimeout(thisTimeout);
thisTimeout = setTimeout(function(){
thisError.html("You must have at least 2 characters");
thisError.show();
}, 800);
} else {
clearTimeout(thisTimeout);
thisError.hide();
thisError.html("");
}
}
});
FYI, this code can be cleaned up a bit too:
var thisTimeout;
$('input').keyup(function(){
var self = $(this);
var thisError = self.parent().siblings('.error');
if (self.hasClass("letters")) {
if(self.val().length <= 1){
clearTimeout(thisTimeout);
thisTimeout = setTimeout(function(){
thisError.html("You must have at least 2 characters");
thisError.show();
}, 800);
} else {
clearTimeout(thisTimeout);
thisError.hide();
thisError.html("");
}
}
});
Upvotes: 2
Reputation: 82614
You may be overwriting the previous setTimeout id. Thus you would not be able to clear it out.
var thisTimeout;
$('input').keyup(function(){
var thisClass = $(this).attr('class').split(" ");
var thisValue = $(this).val();
var thisError = $(this).parent().siblings('.error');
if(thisClass[1] == "letters"){
if(thisValue.length <= 1){
clearTimeout(thisTimeout); // <-- already clear the timeout here before
// starting another one
thisTimeout = setTimeout(function(){
thisError.html("You must have at least 2 characters");
thisError.show();
}, 800);
} else {
clearTimeout(thisTimeout);
thisError.hide();
thisError.html("");
}
}
});
Upvotes: 4