jQuery 使用 jQuery UI 部件工厂编写带状态的插件(翻译)
首先,我們要創建一個progress bar,它只允許我們簡單的設置進度值。正如我們接下來將要看到的,我們需要通過調用 jQuery.widget 及其兩個參數來實現這一操作,這兩個參數分別是:將要創建的插件的名稱,以及一個包含該插件所支持方法的對象字面量(object literal)。
當我們的插件被調用時,它將創建一個新的插件實例,并且包含在該實例上下文(context)中的方法都會被執行。這與標準的jQuery插件有兩個主要的區別。首先,上下文 (context)是一個對象,而不是DOM元素。其次,上下文(context)始終都是一個單獨的對象,而不是集合。
使用 jQuery UI 部件工廠創建一個簡單的,帶狀態的插件:
1 $.widget( "nmk.progressbar", { 2 3 _create: function() { 4 var progress = this.options.value + "%"; 5 this.element.addClass( "progressbar" ).text( progress ); 6 } 7 8 });?插件的名稱必須包含一個命名空間(namespace);在我們的例子當中使用 nmk 作為命名空間(namespace)。關于命名空間(namespace)這里有一個限制,就是它只能夠擁有一個層級;換句話說,我們不能使用類似 nmk.foo 這樣的形式來作為命名空間(namespace)。同時我們看到部件工廠已經為我們提供了兩個屬性。第一個屬性是 this.element ,它是一個只包含一個元素的jQuery對象。如果調用插件的jQuery對象包含多個元素,那么每一個元素將分別擁有一個插件實例,并且每一個插件實例都擁有自己的 this.element 屬性。第二個屬性是 this.options ,該屬性是一個散列,包含有與我們插件選項相對應的所有鍵/值配對。
將選項傳遞給部件:
1 $( "<div />" ).appendTo( "body" ).progressbar({ value: 20 });當我們調用 jQuery.widget 時,它通過向 jQuery.fn 添加一個方法來擴展jQuery(也是我們創建標準插件的方式)。被添加的方法的名稱基于你在調用 jQuery.widget 時所使用的名稱,不包含命名空間(namespace)。在我們的例子當中,它將創建 jQuery.fn.progressbar。傳遞給插件的選項在插件實例內部已經在 this.options 中進行了設置。
正如接下來我們將要展示的,我們可以為任何選項指定一個默認值。當設計API時,你應當想好該插件最常見的使用情形,以便可以設置合適的默認值,并使所有的選項都是完全可選的。
為部件設置默認選項值:
1 $.widget( "nmk.progressbar", { 2 3 // Default options. 4 options: { 5 value: 0 6 }, 7 8 _create: function() { 9 var progress = this.options.value + "%"; 10 this.element.addClass( "progressbar" ).text( progress ); 11 } 12 13 });為部件添加方法
現在我們可以初始化progress bar了,通過調用插件實例中的方法我們使其能夠執行一些操作。要在插件中定義方法,我們只需要在傳遞給 jQuery.widget 的對象字面量(object literal)當中包含該方法。同時我們可以在方法名前面添加下劃線(_)來使其成為私有方法。
創建部件方法:
1 $.widget( "nmk.progressbar", { 2 options: { 3 value: 0 4 }, 5 6 _create: function() { 7 var progress = this.options.value + "%"; 8 this.element.addClass("progressbar").text( progress ); 9 }, 10 11 // Create a public method. 12 value: function( value ) { 13 14 // No value passed, act as a getter. 15 if ( value === undefined ) { 16 17 return this.options.value; 18 19 // Value passed, act as a setter. 20 } else { 21 22 this.options.value = this._constrain( value ); 23 var progress = this.options.value + "%"; 24 this.element.text( progress ); 25 26 } 27 28 }, 29 30 // Create a private method. 31 _constrain: function( value ) { 32 33 if ( value > 100 ) { 34 value = 100; 35 } 36 37 if ( value < 0 ) { 38 value = 0; 39 } 40 41 return value; 42 } 43 44 });?要在插件實例上調用方法,只需要將方法的名稱傳遞給jQuery插件。如果所調用的是帶參數的方法,只需將這些參數放置在方法名的后面。
在插件實例上調用方法:
1 var bar = $( "<div />" ).appendTo( "body").progressbar({ value: 20 }); 2 3 // Get the current value. 4 alert( bar.progressbar( "value" ) ); 5 6 // Update the value. 7 bar.progressbar( "value", 50 ); 8 9 // Get the current value again. 10 alert( bar.progressbar( "value" ) );操縱部件的選項
option方法是插件中內置的方法之一。該方法允許你在初始化之后對屬性進行設置。該方法的工作方式與jQuery的 .css() 和 .attr() 方法相同:你可以通過向其傳遞名稱來將它作為getter,傳遞名稱和值來將它作為setter,傳遞一個鍵/值配對的散列來同時設置多個值。當它被作為getter時,插件將返回與傳遞進來的名稱相對應的選項的當前值。當它被作為setter時,每一個已經設置的選項都會調用插件的 _setOption 方法。當選項發生改變時,我們可以在插件中指定 _setOption 方法來進行反應。
當選項被設置時作出響應:
1 $.widget( "nmk.progressbar", { 2 3 options: { 4 value: 0 5 }, 6 7 _create: function() { 8 this.element.addClass( "progressbar" ); 9 this._update(); 10 }, 11 12 _setOption: function( key, value ) { 13 this.options[ key ] = value; 14 this._update(); 15 }, 16 17 _update: function() { 18 var progress = this.options.value + "%"; 19 this.element.text( progress ); 20 } 21 22 });添加回調函數
添加回調函數讓用戶可以在插件狀態發生變化時作出反應是擴展插件的一種簡單的方式。下面我們將看到如何為progress bar添加回調函數,來表明進度何時到達百分之百。 _trigger 方法帶有三個參數:回調函數的名稱,原生事件對象用于觸發回調函數,以及與事件有關的數據的散列。回調函數的名稱是唯一必要的參數,而其他的參數在用戶希望在插件上實現自己的方法時將十分有用。例如,我們編寫了一個可拖動的插件,當觸發拖動回調函數時,我們可以傳遞一個原生的鼠標移動事件,用戶將可以通過這一事件對象,在 x/y 坐標的基礎上對拖動作出反應。
為用戶擴展提供回調函數:
1 $.widget( "nmk.progressbar", { 2 3 options: { 4 value: 0 5 }, 6 7 _create: function() { 8 this.element.addClass( "progressbar" ); 9 this._update(); 10 }, 11 12 _setOption: function( key, value ) { 13 this.options[ key ] = value; 14 this._update(); 15 }, 16 17 _update: function() { 18 var progress = this.options.value + "%"; 19 this.element.text( progress ); 20 if ( this.options.value == 100 ) { 21 this._trigger( "complete", null, { value: 100 } ); 22 } 23 } 24 25 });回調函數其實就是額外的選項,因此你可以像對待其它選項那樣對其進行設置。每當回調函數被執行時,一個與之對應的事件也會被觸發。事件的名稱由插件的名稱及回調函數的名稱連接而成。回調函數和事件同時接收兩個相同的參數:事件對象和與時間有關的數據的散列,我們將在之后看到相關的演示。
如果你希望插件的某項功能可以被用戶阻止,最好的做法就是創建一個可取消的回調函數。用戶可以像取消原生事件那樣來取消回調函數,或者與之相關的事件:通過調用 event.preventDefault() 或者使用 return false 。如果用戶取消了回調函數, _trigger 方法將返回 false 使得你可以在插件中實現合適的功能。
綁定部件事件:
1 var bar = $( "<div />" ).appendTo( "body" ).progressbar({ 2 3 complete: function( event, data ) { 4 alert( "Callbacks are great!" ); 5 } 6 7 }).bind( "progressbarcomplete", function( event, data ) { 8 9 alert( "Events bubble and support many handlers for extreme flexibility." ); 10 11 alert( "The progress bar value is " + data.value ); 12 13 }); 14 15 bar.progressbar( "option", "value", 100 );部件工廠:深入(Under the Hood)
當你調用 jQuery.widget 時,它會為你的插件創建一個構造函數(constructor),并將你傳遞進來的對象字面量(object literal)作為對象實例的原型(prototype)。所有自動添加到插件中的功能都來自于一個基本的部件原型(widget prototype),它被定義為 jQuery.Widget.prototype。當插件實例被創建之后,它通過 jQuery.data 將插件存儲在原始的DOM元素當中,并使用插件的名稱來作為鍵值。
由于插件實例直接與DOM元素產生聯系,因此如果你愿意的話,可以直接訪問插件實例而非通過插件所暴露的方法。這將允許你直接調用插件實例上的方法,而非通過將方法的名稱作為字符串傳遞給插件,此外你還將可以直接訪問插件的屬性。
1 var bar = $( "<div />") 2 .appendTo( "body" ) 3 .progressbar() 4 .data( "progressbar" ); 5 6 // Call a method directly on the plugin instance. 7 bar.option( "value", 50 ); 8 9 // Access properties on the plugin instance. 10 alert( bar.options.value );插件的構造函數(constructor)和原型(prototype)所擁有的巨大好處之一就是使插件更易擴展。通過在插件原型(prototype)上添加或修改方法,我們可以改變插件所有實例的行為。例如,如果我們想要在progress bar中添加一個方法,用于重置進度為零。我們可以在插件的原型上添加這一方法,并且它立刻就可以被任意插件的實例所調用。
1 $.nmk.progressbar.prototype.reset = function() { 2 this._setOption( "value", 0 ); 3 };清理
在某些情況下,允許用戶隨時應用和取消應用插件將十分有用。你可以通過使用 destroy 方法來達成這一目的。在 destroy 方法當中,你應當撤銷插件在初始化時或之后的使用中所進行的一切動作。 destroy 方法將在被插件所關聯的元素從DOM當中被移除時,自動被調用,因此這同樣可以用來進行垃圾回收。默認情況下, destroy 方法會移除DOM元素和插件實例間的聯系, 因此在插件的 destroy 方法中調用基類的方法十分的重要。
為部件添加 destroy 方法:
1 $.widget( "nmk.progressbar", { 2 3 options: { 4 value: 0 5 }, 6 7 _create: function() { 8 this.element.addClass("progressbar"); 9 this._update(); 10 }, 11 12 _setOption: function( key, value ) { 13 this.options[ key ] = value; 14 this._update(); 15 }, 16 17 _update: function() { 18 var progress = this.options.value + "%"; 19 this.element.text( progress ); 20 if ( this.options.value === 100 ) { 21 this._trigger( "complete", null, { value: 100 } ); 22 } 23 }, 24 25 destroy: function() { 26 this.element 27 .removeClass( "progressbar" ) 28 .text( "" ); 29 30 // Call the base destroy function. 31 $.Widget.prototype.destroy.call( this ); 32 } 33 34 });總結
部件工廠是創建帶狀態插件的唯一方法。有少數一些不同的模型可以被使用,并且它們各有千秋。部件工廠為你解決了大部分常見的問題并且極大的提升了工作效率,它同時提升了代碼的復用率,使其和其它帶狀態的插件一樣的更加適用于jQuery UI。
?
原文地址:http://learn.jquery.com/plugins/stateful-plugins-with-widget-factory/
轉載于:https://www.cnblogs.com/joysoy/p/3537786.html
總結
以上是生活随笔為你收集整理的jQuery 使用 jQuery UI 部件工厂编写带状态的插件(翻译)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转载] 30分钟泛型教程
- 下一篇: 百度地图API使用之实现定位