Hea*_*rab 2 javascript html5 prototype object onload
我想在加载所有需要的图像时调用一个函数.图像的数量是预先知道的,所以我尝试将函数调用附加到每个图像的onload事件并计算它被调用的次数.
<html>
<head>
<script>
var tractor;
function Tractor()
{
this.init_graphics();
}
Tractor.prototype.init_graphics = function()
{
this.gr_max = 3;
this.load_count = 0;
this.loading_complete(); // #1 test call, works OK
this.img1 = new Image();
this.img1.onload = this.loading_complete; // #2 gets called, but gr_max = undefined, load_count = NaN
this.img1.src = "http://dl.dropbox.com/u/217824/tmp/rearwheel.gif"; //just a test image
}
Tractor.prototype.loading_complete = function()
{
this.load_count += 1;
alert("this.loading_complete, load_count = " + this.load_count + ", gr_max = " + this.gr_max);
if(this.load_count >= this.gr_max) {this.proceed();}
};
function start()
{
tractor = new Tractor();
}
</script>
</head>
<body onload="start();">
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
当它刚刚从对象的另一个函数调用时(参见#1),它就像我预期的那样工作.但是,当从onload事件调用它时(参见#2),变量变为"未定义"或"NaN"等.发生了什么?我究竟做错了什么?我如何使其工作?
我不记得曾经在Javascript中创建自己的对象,所以我当然对这个"我的代码有什么问题"这个问题深表歉意.我主要使用本文作为参考,第1.2节.
为了以防万一,我在http://jsfiddle.net/ffJLn/上放了相同的代码
bind
回调的上下文:
this.img1.onload = this.loading_complete.bind(this);
Run Code Online (Sandbox Code Playgroud)
请参阅:http://jsfiddle.net/ffJLn/1/(与您的相同,但有此添加)
以下是对bind
详细工作原理的解释:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
基本思想是它使this
绑定函数等于你传递的任何参数bind
.
另一个选择是创建一个闭包:
var self = this;
this.img1.onload = function() { self.loading_complete() };
Run Code Online (Sandbox Code Playgroud)
闭包是保持对其上下文的引用的函数(事实上,javascript中的所有函数都以这种方式工作).所以在这里你要创建一个匿名函数来保持对它的引用self
.所以这是维持背景和loading_complete
拥有权利的另一种方式this
.
请参阅:http://jsfiddle.net/ffJLn/2/(与您的相同,但有第二种可能性)