2013-01-19 1 views
8

jQueryクラスを理解しようとしていますが、うまくいきません。jQueryでシンプルなJavaScriptクラスを作成する

が私の目標は、クラスをこのように使用するために(またはそれを行うには良い方法を学ぶこと)である。

var player = new Player($("playerElement")); 
player.InitEvents(); 

は、他の人の例を使用して、これは私が試したものです:

$.Player = function ($) { 

}; 

$.Player.prototype.InitEvents = function() { 

    $(this).keypress(function (e) { 
     var key = e.which; 
     if (key == 100) { 
      MoveRight(); 
     } 
     if (key == 97) { 
      MoveLeft(); 
     } 
    }); 
}; 

$.Player.prototype.MoveRight = function() { 
    $(this).css("right", this.playerX += 10); 
} 

$.Player.prototype.MoveLeft = function() { 
    $(this).css("right", this.playerX -= 10); 
} 

$.Player.defaultOptions = { 
    playerX: 0, 
    playerY: 0 
}; 

最終的な目標は、キーボードの文字「A」と「D」を使用して、文字を画面上で左右に動かすことです。

私はこの "クラス"で何か非常に間違っていると感じていますが、私はなぜそれがわかりません。

+0

'this'インスタンスメソッド内でインスタンスオブジェクトを参照しますそれ自身で '$(this).keypress'、' $(this).css'などは 'this'はDOM要素やクエリ文字列を参照しないので使用できません。あなたの関数呼び出しも間違っています。これは 'これを読むべきです。MoveRight() 'しかし、' this'コンテキストをDOM要素自体に設定するjQueryハンドラの中にあるように、スコープチェーン内のレベルアップする変数にインスタンスの 'this'を割り当てる必要がありますハンドラの内部で 'MoveRight' /' MoveLeft'メソッドを呼び出すことができます。 –

+0

私が行った問題を解決するためにコードを変更する方法を教えていただけますか?私が良いコードと私のコードを比較することができれば、私が何をしたのかを見るのがずっと簡単になります。 (あまりにも難しくない場合) – samy

+0

私は人を試すことができますが、それは "修正"より完全な書き換えに近いです。 ':P'私は簡単な例を作ることができるかどうかを見ていきます。 –

答えて

19

重要な問題は、あなたがthis.elementに渡されたjQueryオブジェクト/要素を割り当てる必要があるということです - または別のthis.propertyName - だから後でインスタンスのメソッドの内部でアクセスできます。

MoveRight()/MoveLeft()は、スコープチェーンで定義されているのではなく、インスタンスのコンストラクタのプロトタイプで定義されているため、呼び出すことはできません。

が更新され、以下のコードを次のようにコメントし

(function ($) { //an IIFE so safely alias jQuery to $ 
    $.Player = function (element) { //renamed arg for readability 

     //stores the passed element as a property of the created instance. 
     //This way we can access it later 
     this.element = (element instanceof $) ? element : $(element); 
     //instanceof is an extremely simple method to handle passed jQuery objects, 
     //DOM elements and selector strings. 
     //This one doesn't check if the passed element is valid 
     //nor if a passed selector string matches any elements. 
    }; 

    //assigning an object literal to the prototype is a shorter syntax 
    //than assigning one property at a time 
    $.Player.prototype = { 
     InitEvents: function() { 
      //`this` references the instance object inside of an instace's method, 
      //however `this` is set to reference a DOM element inside jQuery event 
      //handler functions' scope. So we take advantage of JS's lexical scope 
      //and assign the `this` reference to another variable that we can access 
      //inside the jQuery handlers 
      var that = this; 
      //I'm using `document` instead of `this` so it will catch arrow keys 
      //on the whole document and not just when the element is focused. 
      //Also, Firefox doesn't fire the keypress event for non-printable 
      //characters so we use a keydown handler 
      $(document).keydown(function (e) { 
       var key = e.which; 
       if (key == 39) { 
        that.moveRight(); 
       } else if (key == 37) { 
        that.moveLeft(); 
       } 
      }); 

      this.element.css({ 
       //either absolute or relative position is necessary 
       //for the `left` property to have effect 
       position: 'absolute', 
       left: $.Player.defaultOptions.playerX 
      }); 
     }, 
     //renamed your method to start with lowercase, convention is to use 
     //Capitalized names for instanceables only 
     moveRight: function() { 
      this.element.css("left", '+=' + 10); 
     }, 
     moveLeft: function() { 
      this.element.css("left", '-=' + 10); 
     } 
    }; 


    $.Player.defaultOptions = { 
     playerX: 0, 
     playerY: 0 
    }; 

}(jQuery)); 

//so you can use it as: 
var player = new $.Player($("#playerElement")); 
player.InitEvents(); 

Fiddle

はまた、JavaScriptが定義によって関連付けられている実際の「クラス」(少なくともES6が実装されますないまで)やメソッドを(持っていないことに注意してくださいクラスに似ている甘い構文を提供するコンストラクタです。ここでJSの「偽」方法に関するTJクラウダーが書いた素晴らしい記事だ、それは少し高度ですが、誰もがそれを読んでから、新しい何かを学ぶことができる必要があります:
http://blog.niftysnippets.org/2008/03/mythical-methods.html

2

あなたPlayerプロトタイプの機能を、現在のプレーヤーオブジェクトへthisポイント内部thisを使用する(私の英語のため申し訳ありません)

$(this).keypressを使用する場合は、thisがHTML要素を指している必要があります。

2つは単純に互換性がありません。 thisは1つのみで、現在のPlayerオブジェクトを指し、HTML要素は指していません。

問題を解決するには、HTML要素を作成時に、または関連する関数呼び出しに渡す必要があります。

あなたは、このように構築時にPlayerオブジェクトに要素を渡すことができます。

$.Player = function ($, element) { 
     this.element = element; 

}; 

$.Player.prototype.InitEvents = function() { 

    $(this.element).keypress(function (e) { 
     var key = e.which; 
     if (key == 100) { 
      MoveRight(); 
     } 
     if (key == 97) { 
      MoveLeft(); 
     } 
    }); 
}; 

$.Player.prototype.MoveRight = function() { 
    $(this.element).css("right", this.playerX += 10); 
} 

$.Player.prototype.MoveLeft = function() { 
    $(this.element).css("right", this.playerX -= 10); 
} 

$.Player.defaultOptions = { 
    playerX: 0, 
    playerY: 0 
}; 
+0

私の知らないことは申し訳ありませんが、どうすればこのクラスを使用できますか?私はなぜそれを使用する場合私は私のqustionでそれがdosnt仕事を表示することを意味します。 (それほど難しくない場合)例を追加できますか? (私の質問に答える時間をとってくれてありがとう) – samy

関連する問題