2012-03-14 14 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

バインドされた関数内のthisを、パラメータとしてbindに渡すものと等しくするということです。

別のオプションは、クロージャを作成することです:

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

クロージャ(ジャバスクリプト作業中のすべての機能を、実際にこの方法を)そのコンテキストへの参照を保持する機能です。ここでは、selfへの参照を保持する無名関数を作成しています。これは文脈を維持し、loading_completeが右を持つ別の方法ですthis

参照:#2が呼び出されるときhttp://jsfiddle.net/ffJLn/2/(あなたと同じですが、第二の可能性あり)

2

、あなたのthisが変更されました。 thisは、Tractorオブジェクトではなくnew Image()を参照するようになりました。

...変更

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

this.img1.onload = this.loading_complete; 

をお試しください

関連する問題