2013-01-19 11 views
8

Próbuję zrozumieć klasy jQuery, ale to nie idzie zbyt dobrze.Tworzenie prostej klasy JavaScript z jQuery

Moim celem jest użycie klasy w ten sposób (lub nauczyć się lepszego sposobu, aby to zrobić):

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

Korzystanie przykłady innych ludzi, to jest to, czego próbowałem:

$.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 
}; 

Celem końcowym jest przeniesienie postaci na lewy i prawy ekran za pomocą liter klawiatury A i D.

Mam przeczucie, że robię coś bardzo nie tak z tą "klasą" , ale nie jestem pewien dlaczego.

(przepraszam za mój angielski)

+0

'this' wewnątrz metody instancji odwołuje się do obiektu instancji więc nie można użyć '$ (this) .keypress',' $ (this) .css' itp, ponieważ 'this' nie odwołuje się do elementu DOM ani do ciągu zapytania. Twoje wywołania funkcji również są błędne, należy przeczytać "to.MoveRight() 'ale gdy jesteś wewnątrz programu obsługi jQuery, który ustawia kontekst' this' na sam element DOM, będziesz musiał przypisać instancję 'this' do zmiennej o poziom wyżej w łańcuchu zasięgu, abyś mógł uzyskaj dostęp do wewnątrz programu obsługi, aby wywołać metody 'MoveRight' /' MoveLeft'. –

+0

czy możesz pokazać mi, jak zmienisz mój kod, aby rozwiązać problem, który popełniłem? znacznie łatwiej będzie mi zobaczyć, co zrobiłem, gdybym mógł przedstawić dobry kod w stosunku do mojego. (jeśli nie jest to zbyt trudne) – samy

+0

Mogę spróbować człowieka, ale jest on bliższy kompletnej przeróbce niż "poprawka". ': P' Zobaczę, czy mogę zrobić prosty przykład. –

Odpowiedz

19

Ważną kwestią jest to, że trzeba przypisać przeszedł jQuery obiekt/elementu do this.element - lub innego this.propertyName - więc może uzyskać do niego dostęp później w metodach instancji.

Tak samo bezpośrednio nie można wywołać MoveRight()/MoveLeft(), ponieważ te funkcje nie są zdefiniowane w łańcuchu zasięgu, ale raczej w prototypie konstruktora instancji, dlatego do wywołania tych elementów potrzebne jest odwołanie do samej instancji.

Zaktualizowany i skomentował poniższy kod:

(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

również pamiętać, że JavaScript nie ma rzeczywiste „klas” (przynajmniej nie aż ES6 zostanie wdrożone) ani metod (które z definicji są związane wyłącznie dla klas), ale raczej Konstruktory, które zapewniają słodką składnię, która przypomina klasy. Oto niesamowite artykuł napisany przez TJ Crowder dotyczące „fałszywych” metod JS jest, że jest to mało zaawansowane, ale każdy powinien być w stanie nauczyć się czegoś nowego od czytania go:
http://blog.niftysnippets.org/2008/03/mythical-methods.html

2

Podczas korzystania this wewnątrz firmy Player funkcji prototyp this punktów do bieżącego obiektu Player.

Ale jeśli używasz $(this).keypress, wymaga to, aby this wskazywało element HTML.

Dwa są po prostu niezgodne. Jest tylko jeden this i wskazuje na bieżący obiekt Player, a nie na element HTML.

Aby rozwiązać problem, musisz przekazać element HTML do obiektu odtwarzacza po jego utworzeniu lub do odpowiednich wywołań funkcji.

można przekazać elementu do obiektu gracza podczas konstrukcji jak ta:

$.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

przepraszam za moją ignorancję, ale w jaki sposób mogę użyć tej klasy? mam na myśli, jeśli używam tego, dlaczego pokazuję w moim qustion to dosnt praca. (jeśli to nie takie trudne) czy możesz dodać przykład? (dziękuję za poświęcenie czasu, aby odpowiedzieć na moje pytanie) – samy

Powiązane problemy