標題: 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
|
就翻譯到這了。差不多也算是我的理解吧,可能翻譯的不好歡迎指正。