2012-03-14 44 views
2

我想在加載所有所需圖像時調用函數。圖像的數量是預先知道的,所以我試着給每個圖像的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> 

當它剛剛從對象的另一個函數(請參閱#1)中調用時,它的工作方式與我的預期相同。但是,當它從onload事件中調用時(參見#2),變量變成「未定義」或「NaN」或其他東西。發生了什麼?我究竟做錯了什麼?我如何使它工作?

我不記得曾經在Javascript中創建過自己的對象,所以我當然非常爲這個「我的代碼出了什麼問題」類問題深表歉意。我主要使用this article作爲參考,第1.2節。

以防萬一,我把相同的代碼上http://jsfiddle.net/ffJLn/

回答

7

bind上下文回調:

this.img1.onload = this.loading_complete.bind(this); 

見:http://jsfiddle.net/ffJLn/1/(和你的一樣,但是帶有附加)

這裏的bind詳細說明如何工作:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

該bas ic想法是它使得綁定函數中的this等於您傳遞給bind的任何參數。

另一種選擇是創建一個封閉:

var self = this; 
this.img1.onload = function() { self.loading_complete() }; 

閉包是不斷引用其上下文功能(實際上,所有的功能在JavaScript中工作這種方式)。所以在這裏你要創建一個匿名函數來保持對self的引用。所以這是維護背景的另一種方式,並且loading_complete擁有正確的this

見:http://jsfiddle.net/ffJLn/2/(和你的一樣,但與第二種可能性)

2

當#2被調用,您this發生了變化。 this現在是指new Image()而不是Tractor對象。

嘗試改變...

this.img1.onload = this.loading_complete; 

var that = this; 
this.img1.onload = function() { that.loading_complete(); }; 
相關問題