-1

私はjsでoopするのが初めてです。私は Box2dWeb を使用して HTML5 ゲームに取り組んでおり、完全に oop ベースにする必要があると判断しました。そこで、このような物理クラスを別のファイルに作成しましたphysics.js

(function(window) 
{
function Physics(element, scale){
//init world logic
    }

Physics.prototype.debug = function(){
           //debug draw logic
};

Physics.prototype.step = function(dt){
    //step logic
};

    //making this class(or object) visible on the global scope
    //so i can create vars of this type anywhere in the application
window.Physics = Physics;
}(window));

これで、ゲームの物理、グラフィック、アセットなどをすべて初期化するメインgame.jsファイルができました。内容は次のとおりです。

(function(){
 function init(){
    var physics = new Physics(document.getElementById("b2dCanvas"), 30);
    console.log(physics);
    physics.debug();
}
window.addEventListener("load", init);
 }());

このファイルは、物理オブジェクトを問題なく初期化します。最終的にこれが私が欲しいものです。すごい!しかし、これ以前のファイルはこのようなもので、init()機能はありませんでした。

(function(){

    var physics = new Physics(document.getElementById("b2dCanvas"), 30);
    console.log(physics);
    physics.debug();
 }());

これは明らかにエラーを投げましたUncaught TypeError: Cannot call method 'getContext' of null。これは、私が呼び出さなくても、物理コンストラクターが呼び出されていたことを意味します (そして当然element、この時点では null でした)。それはどのように可能でしたか?私の自己実行関数は、オブジェクトを正しくgame.js初期化する必要がありましたか? Physics私は何が欠けていますか?

4

4 に答える 4

2

HTML が完全に解析される前、および canvas 要素が DOM に追加される前に、スクリプトが実行されていました。を追加window.addEventListener("load", init);したとき、 window.onload イベントがトリガーされたときに実行するようにしました。その時点で、DOM は完全に解析されました。

最新のブラウザでは、それを次のように置き換えることもできます

document.addEventListener("DOMContentLoaded", init);

そのイベントは、DOM の準備ができたときにトリガーされますが、(onload とは異なり) 画像などの他のリソースを待機しません。

または、body タグを閉じる直前にすべてのスクリプトを追加します。その時点で、ボディ内のすべての HTML タグはすでに DOM に挿入されています。

于 2013-03-04T20:05:02.647 に答える
1

これは、私が呼び出さなくても、物理コンストラクターが呼び出されていたことを意味します (そして、当然、この時点の要素は null でした)。それはどのように可能でしたか?

次の構文を使用して呼び出しているためです。

(function(){...}());
                ^^
               call

これは、スクリプトが通常のページ スクリプト解析の一部として解析されるときに関数を呼び出し、ドキュメント/DOM が操作できるようになるまで待機しません。ある種のドキュメント「ロード」リスナーを使用するか、その特定の構文を削除して、DOM の準備が整ったときに関数を手動で呼び出す必要があります。

于 2013-03-04T20:04:30.110 に答える
0

このエラーは、物理オブジェクトの準備ができていないこととは関係ありません。コードが呼び出されたときにページ上にない要素を参照しようとする内部のコードに関係しています。

あなたが呼んでいたのは簡単です

document.getElementById("b2dCanvas")

要素がページにロードされる前。getElementById が何も見つからない場合、null を返します。

あなたがそれを検査した場合、あなたのコードはどのように見えるでしょうか

var physics = new Physics(null, 30);

そして要素はnullです

function Physics(element, scale){  
    var ctx = element.getContext("2d");  //<-- where the error occurs since element is null

したがって、エラー: Uncaught TypeError: Cannot call method 'getContext' of null.

load イベントをリッスンすると、要素がそこにあることを意味するため、問題なく読み込まれます。これに対処する別の方法は、ページの下部にスクリプトを追加することです。

于 2013-03-04T20:04:06.083 に答える
0

私の推測では、DOM の準備が整う前に関数を呼び出していると思います。スクリプト インクルードをコードの最後に配置するか、ウィンドウ ロード リスナーをすべてラップするだけでよいでしょう。

于 2013-03-04T20:04:48.340 に答える