我想了解jQuery的类,但它不会很好。
我的目标是使用一类这个方法(或想了解一个更好的方式来做到这一点):
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
。
我有我做得非常不对的“类”的感觉,但我不知道为什么。
(对不起我的英语不好)
一个重要的问题是,你必须要传递的jQuery对象/元素的分配this.element
-或其他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();
小提琴
还要注意的是JavaScript并没有实际的“类”(至少直到ES6得到实施)也没有方法(其定义是专门关联类),而是它的构造提供了一个甜蜜的语法类似于类。 下面是关于JS的“假”的方法由TJ克罗德写的真棒文章,这是一个有点先进的,但每个人都应该能学到新的东西从阅读它:
http://blog.niftysnippets.org/2008/03/mythical-methods.html
当你使用this
里面你的Player
原型的功能, this
点到目前Player对象。
但是,当你使用$(this).keypress
它要求this
指向一个HTML元素。
这两个根本是不相容的。 只有一个this
,它指向当前播放的对象,而不是一个HTML元素。
要解决你的问题,你需要将HTML元素传递到在其创建或进入相关的函数调用Player对象。
您可以将元素成在建设这样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
};