2013-01-19 32 views
8

Tôi đang cố gắng hiểu các lớp jQuery nhưng nó không hoạt động tốt.Tạo một lớp JavaScript đơn giản với jQuery

Mục tiêu của tôi là sử dụng một lớp học theo cách này (hoặc để tìm hiểu một cách tốt hơn để làm điều đó):

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

Sử dụng ví dụ của người khác, đây là những gì tôi đã cố gắng:

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

Mục tiêu cuối cùng là để một nhân vật di chuyển trên màn hình sang trái và phải bằng các chữ cái trên bàn phím AD.

Tôi có cảm giác rằng tôi đang làm điều gì đó rất sai với "lớp học" nhưng tôi không chắc chắn tại sao.

(xin lỗi vì tiếng Anh của tôi)

+0

'this' bên trong phương pháp dụ tham chiếu đối tượng thể hiện chính vì vậy bạn không thể sử dụng '$ (this) .keypress',' $ (this) .css', vd 'this' không tham chiếu đến một phần tử DOM hay chuỗi truy vấn. Các cuộc gọi hàm của bạn cũng sai, nó sẽ đọc 'này.MoveRight() 'nhưng khi bạn đang ở trong một trình xử lý jQuery đặt ngữ cảnh' this' này thành chính phần tử DOM, bạn sẽ cần gán giá trị 'this' này cho một biến một cấp trong chuỗi phạm vi để bạn có thể truy cập nó bên trong trình xử lý để gọi các phương thức 'MoveRight' /' MoveLeft' của nó. –

+0

bạn có thể chỉ cho tôi cách bạn sẽ thay đổi mã của mình để khắc phục sự cố tôi đã thực hiện không? nó sẽ dễ dàng hơn nhiều cho tôi để xem những gì tôi đã làm worng nếu tôi có thể compre một mã tốt vs của tôi. (nếu không quá khó) – samy

+0

Tôi có thể thử người đàn ông, nhưng nó gần gũi hơn với một viết lại hoàn chỉnh hơn là "sửa chữa". ': P' Tôi sẽ xem nếu tôi có thể làm một ví dụ đơn giản. –

Trả lời

19

Một vấn đề quan trọng là bạn phải giao cho jQuery đối tượng/yếu tố truyền cho một this.element - hoặc this.propertyName khác - vì vậy bạn có thể truy cập nó sau này bên trong các phương thức của cá thể.

Bạn cũng không thể gọi trực tiếp MoveRight()/MoveLeft() vì các hàm này không được xác định trong chuỗi phạm vi, mà là trong nguyên mẫu của Constructor của bạn, do đó bạn cần tham chiếu đến cá thể đó để gọi chúng.

cập nhật và nhận xét mã bên dưới:

(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

Cũng lưu ý rằng JavaScript không có "lớp học" thực tế (ít nhất là không cho đến khi ES6 được thực hiện) hay phương pháp (mà theo định nghĩa có liên quan dành riêng cho Lớp học), nhưng đúng hơn là các Nhà xây dựng cung cấp một cú pháp ngọt ngào giống với các lớp học. Dưới đây là một bài báo tuyệt vời được viết bởi TJ Crowder liên quan đến phương pháp "giả" JS, nó là một chút cao, nhưng tất cả mọi người sẽ có thể học hỏi những điều mới mẻ từ việc đọc nó:
http://blog.niftysnippets.org/2008/03/mythical-methods.html

2

Khi bạn sử dụng this bên Player chức năng nguyên mẫu của bạn, this điểm đến đối tượng Player hiện hành.

Nhưng khi bạn sử dụng $(this).keypress, yêu cầu phải this điểm đến phần tử HTML.

Hai đơn giản là không tương thích. Chỉ có một this và nó trỏ đến đối tượng Trình phát hiện tại, chứ không trỏ đến phần tử HTML.

Để khắc phục sự cố của bạn, bạn sẽ cần phải chuyển phần tử HTML vào đối tượng Trình phát khi tạo hoặc vào các cuộc gọi hàm có liên quan.

Bạn có thể vượt qua các phần tử vào đối tượng Player khi xây dựng như thế này:

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

xin lỗi vì sự thiếu hiểu biết của tôi nhưng làm thế nào để tôi sử dụng lớp học này? tôi có nghĩa là nếu tôi sử dụng nó lý do tại sao tôi hiển thị trong qustion của tôi nó dosnt làm việc. (nếu không phải là khó khăn như vậy) bạn có thể thêm một ví dụ? (cảm ơn bạn đã dành thời gian trả lời câu hỏi của tôi) – samy

Các vấn đề liên quan