12 April, 2006

0 is false !

When using || or && to test between several expressions which is the first to be true and taken as the whole value, be carefull with numbers! I had a bas experience this morning using a decremential counter.

I was doing some code 10 times and then reinitializing the counter for the next use of the function. In the context of a DIV Element, my code was the following:

//Function to make DIV blink
this.blink = function() {
//Blink 10 times
this.times = (this.times-1)||10;
//If not 10 times yet
if ( this.times > 0 ) {
//Switch blink color
if ( this.times%2==0 )
this.style.backgroundColor = '#000';
else
this.style.backgroundColor = '#FFF';
this_ = this;
//Redo blink in 50 milliseconds
setTimeout('this_.blink()', 50);
else { //Times out, stop blinking, reset counter value
clearTimeout();
this.times = 10;
}
}

My point is on the very first line of the function:
this.times = (this.times-1)||10;
What it does is affecting 10 when this.times doesn't exist yet and then affects 9, 8, 7,...
But when it comes to 0, then the right operand choose 10 instead of 0 because 0 is considered as false. So it's going again and again without stopping from blinking!
I better stop at 1, which will work.

3 comments:

Anonymous said...

I've been messing up with your blink code, to make it triggerable from a

body onload="blink('mydiv')"

Here is the code I have:

function blink(e) {
ele = document.getElementById(e);

times = 20;

if ( times > 0 ) {
//Switch blink color
if ( times%2==0 ){
ele.style.backgroundColor = '#000';
}else{
ele.style.backgroundColor = '#FFF';
}
//Redo blink in 50 milliseconds
setTimeout('blink('+this.ele.id+')', 50);
times--;
}else{
//Times out, stop blinking, reset counter value
clearTimeout();
times = 20;
}
}


It seems like I can't recall my element (ele).
Any ideas why ?

Thanks

Nicolas Faugout said...

Hi!
There are two things you miss in your code.
First, you should assign times = 20 outside of the blink function, otherwise, times will always be 20 and times%2 will always equals 0 and your DIV will always have a black background and not blink.
Second, you have a this.ele.id in your code where I don't see any object with a ele attribute. Simply type ele.id
Now it works!

Anonymous said...

Brilliant, thank you very much :)