标题: jQuery Widget 开发 Tutorial
- Roamman 2010-02-02 07:56 阅读:35
- 评论:0 | 添加评论 | 返回 ↓
原文:http://bililite.com/blog/understanding-jquery-ui-widgets-a-tutorial/
由于翻译后不能使用HTML和SCRIPT所以演示部分就不能看到了,请参照原文。
写这篇文章的目的是为了让我理解并开发出我自己的Widgets,同时我也希望这篇文章能对其他人也有帮助。Widget让我说就是一种用户界面元 素,类似于按钮或者像复杂的DatePicker(日期选择控件)。但这一概念对于jQuery,更确切的说是一个类。这个类的成员与一些HTML元素相 关,比如Draggable和Sortable。当然不是所有Widget都使用$.widget,例如datePicker就没有使用。
插件:修改元素
让我们用一个带CSS类的P元素作为目标举个例子。
-
1
|
-
<p class="target">This is a paragraph</p>
|
我们把它变绿:
-
1
|
-
$(".target").css({"background":'green'});
|
然后我们需要将这一功能更通用化:
-
1
|
-
$.fn.green = function() {return this.css({background: 'green'})}
|
上面的代码是我们可以在任意的选中元素上产生效果,但他没有让我们保持和某个元素的关联。例如如果我们需要制作一个恢复背景的功能,哪么我们必须确定他的初始颜色。如果要设计一个Darker(),我们就必须知道元素现在是什么颜色。
保持插件状态
我们可以创建一个与某元素管理单的对象:
-
|
-
element.myobject = new Myobject({'target': element})
-
-
$.fn.green2 = function() {
-
return this.each(function(){
-
if (!this.green) this.green = new Green(this); // associate our state-keeping object with the element
-
this.green.setLevel(15);
-
});
-
};
-
$.fn.off = function() {
-
return this.each(function(){
-
if (this.green) this.green.setLevel(16);
-
delete this.green; // recover the memory
-
});
-
};
-
$.fn.darker = function() {
-
return this.each(function(){
-
if (this.green) this.green.setLevel(this.green.getLevel()-1);
-
});
-
};
-
$.fn.lighter = function() {
-
return this.each(function(){
-
if (this.green) this.green.setLevel(this.green.getLevel()+1);
-
});
-
};
-
-
function Green(target){
-
greenlevels = ['#000','#010','#020','#030','#040','#050','#060','#070','#080','#090','#0a0','#0b0','#0c0','#0d0','#0e0','#0f0','#fff'];
-
this.target = target; // associate the element with the object
-
this.level = 0;
-
this.getLevel = function() { return this.level; }
-
this.setLevel = function(x) {
-
this.level = Math.floor(Math.min(greenlevels.length-1, Math.max(0,x)));
-
this.target.css({background: greenlevels[this.level]});
-
}
-
};
|
但是上面这种方式使得$.fn命名空间中出现了很多函数。我们也可以在该命名空间内再创建一个命名空间,但一般的设计思路使用一个字符串来调用相应的函数,即我们可以使用类似element.green2("darker")来调用darker()方法:
-
|
-
$.fn.green2 = function(which){
-
return this.each(function(){
-
if (which === undefined){ // initial call
-
if (!this.green) this.green = new Green($(this)); // associate our state-keeping object with the element
-
this.green.setLevel(15);
-
}else if (which == 'off'){
-
if (this.green) this.green.setLevel(16);
-
delete this.green
-
}else if (which == 'darker'){
-
if (this.green) this.green.setLevel(this.green.getLevel()-1);
-
}else if (which == 'lighter'){
-
if (this.green) this.green.setLevel(this.green.getLevel()+1);
-
}
-
});
-
};
-
-
function Green(target){
-
greenlevels = ['#000','#010','#020','#030','#040','#050','#060','#070','#080','#090','#0a0','#0b0','#0c0','#0d0','#0e0','#0f0', '#fff'];
-
this.target = target; // associate the element with the object
-
this.level = 0;
-
this.getLevel = function() { return this.level; }
-
this.setLevel = function(x) {
-
this.level = Math.floor(Math.min(greenlevels.length-1, Math.max(0,x)));
-
this.target.css({background: greenlevels[this.level]});
-
}
-
};
|
插件与对象关联所带来的问题 上面的方式能够方便的写出程序,但是也带来了循环引用和可能的内存漏洞。浏览器对于Javascript和Dom元素是使用不同的垃圾回收方式,上面的引用方式可能就会带来问题,使得回收不能正常进行。 我们同时也要注意,在我们开发插件是也要注意内存的回收。 jQuery用$.fn.data解决了这一问题:
-
1
|
-
$(element).data('myobject', new Myobject({'target': element}))
|
但是,这样做的同时又带来了其他的问题,我们需要做很多“额外”的工作,这些工作与程序逻辑毫无关系,重复而无用。所以重复实现这一功能,需要抽象出来减 少工作。 解决问题:$.widget 这就是$.widget出现的原因。它使得插件中的Javascript类的单个实例与每个元素相关联,这样我们在与对象进行交互操作元素的时候就不会带 来内存绣楼的问题。 同上面一样,你还是需要创建类的构造函数。与之不同的是,我们需要一个包含了相关方法的“原型”。同时也有一些变化,如:_init()函数在构造是调 用,destroy()方法在析构是调用。这两个函数都是预先定义的,不过你可以覆盖。element和上面我们的target是与类相关的jQuery 对象。 Widget中所有已“_”开头的方法都属预定义似有形函数,外部不能调用。
-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
|
-
var Green3 = {
-
_init: function() { this.setLevel(15); },
-
greenlevels: ['#000','#010','#020','#030','#040','#050','#060','#070','#080','#090','#0a0','#0b0','#0c0','#0d0','#0e0','#0f0', '#fff'],
-
level: 0,
-
getLevel: function() { return this.level; },
-
setLevel: function(x) {
-
this.level = Math.floor(Math.min(this.greenlevels.length-1, Math.max(0,x)));
-
this.element.css({background: this.greenlevels[this.level]});
-
},
-
darker: function() { this.setLevel(this.getLevel()-1); },
-
lighter: function() { this.setLevel(this.getLevel()+1); },
-
off: function() {
-
this.element.css({background: 'none'});
-
this.destroy(); // use the predefined function
-
}
-
};
|
上述代码即就是整个程序逻辑,使用下面代码生成插件:
-
1
|
-
$.widget("ui.green3", Green3); // create the widget
|
就翻译到这了。差不多也算是我的理解吧,可能翻译的不好欢迎指正。