Javascript setInterval question
I noticed something that I can't quite explain. I made this javascript code that grows or shrinks a blue box. The script is here:
var animated = {
timer : null,
el : document.getElementById("divNavyBox"),
startGrowAnimation : function() {
this.stopAnimation();
this.timer = setInterval(
animated.doAnimation(5), 10);
},
startShrinkAnimation : function() {
this.stopAnimation();
this.timer = setInterval(function() {
animated.doAnimation(-5);
}, 10);
},
stopAnimation : function() {
clearInterval(this.timer);
},
doAnimation : function(amount) {
var size = this.el.offsetWidth;
if ((amount > 0 && size < 200) || (amount < 0 && size > 0)) {
this.el.style.width = size + amount + "px";
this.el.style.height = size + amount + "px";
} else {
this.stopAnimation();
}
}
};
When the startGrowAnimation method of the animated class is called, the box visually grows until it reaches a certain width开发者_StackOverflow社区 and height. It then stops. The startGrowAnimation code is located below:
startGrowAnimation : function() {
this.timer = setInterval(function() {
animated.doAnimation(5);
}, 10);
}
This code WORKS just fine. However, I don't understand WHY it's necessary to put an anonymous function in the parameter instead of just the normal call function. So, I replaced the code above with the code below:
startGrowAnimation : function() {
this.stopAnimation();
this.timer = setInterval(animated.doAnimation(5), 10);
},
When I use this code, for some reason, the box only increases in size by five pixels each time the startGrowAnimation method is called.
So, why is it necessary to include the startGrowAnimation method inside of an anonymous function call in this case?
That code you tried will call that function and pass the return to setInterval()
. That is obviously not what you want.
If you placed animated.doAnimation
(a reference to the function) as the callback argument, the this
value inside of that function will point to window
, not the object itself. This is because it has lost the context of being called as a method of that object.
So you must call the method as a property of the object. This means you need to use an anonymous function wrapper so its body can be animated.doAnimation()
.
The only other way is not worth mentioning as it invokes an eval()
type function.
精彩评论