1. 程式人生 > >Jquery系列文章之開發外掛(11章)

Jquery系列文章之開發外掛(11章)

   開發Jquery外掛

   本章,我們簡紹 幾種不同外掛的開發方法,有簡單有複雜。首先,從新增新的全域性函式的外掛開始,然後再逐步討論各種形式的jquery物件方法。此外,還將討論以新表示式來擴充套件jquery選擇符引擎,最後在簡紹怎樣把外掛共享給其他開發人員。

 

 

11.1 新增新的全域性函式

   所謂全域性函式,就是jquery物件的方法,但從實踐的角度來說,它們是位於jquery名稱空間內部的函式。例如$.ajax()所作的一切可以通過名為ajax()的常規全域性函式來實現,但這種方式(通過$或jquery直接呼叫方法名)會造成函式命名衝突的問題。解決方法名衝突的方法是,通過將函式放入jquery的不同名稱空間中去。

   要向jquery名稱空間中新增一個函式,只需要將這個函式指定為jquery物件的一個屬性:

    

      

    於是我們就可以在使用這個外掛的任何地方,編寫如下程式碼使用它:

     jquery.globalFunction();

或通過別名$寫成:

     $.globalFunction();

 

11.1.1 新增多個函式

    如果想在同一個js檔案中提供多個全域性函式,可以獨立地宣告它們:

   

 

 

呼叫它們:

   

 

 

還可以使用$.extend()函式使函式的定義更清晰:

    

以上程式碼會得到同樣的結果。

 

 

   為避免方法名衝突,最好把屬於一個外掛的所有全域性函式都封裝到一個物件中去:

   

 

呼叫時如下:

   

 

 

11.1.2  外掛實用方法

    核心的jquery庫提供了許多全域性函式都是實用方法。即這些方法為頻繁執行任務提供了快捷方式。陣列處理函式$.each()、$.map()、$.grep()都是這方面的例子。下面通過新增一個新的$.sum()方法,來示範如何建立這種實用方法。

 

    這個方法通過接受一個數組引數,並將陣列中的值累加起來,返回結果。程式碼如下:

   

   

   為了測試方法,寫一個頁面,html內容如下:

  

   

接著在編寫一段指令碼,把返回值新增到標籤array-sum上面去:

  

   

continuing...

 

11.2  新增jquery 物件方法

    jquery內建功能大部分都是通過其物件的方法提供的,而這些方法也是外掛之所以誘人的關鍵。當函式需要操作DOM元素時,就是將函式建立為jquery物件方法的好機會。

     新增例項方法與新增全域性方法類似,但擴充套件的是jquery.fn(jquery.prototype的別名)物件:

    jquery.fn.myMethod=function(){

    alter('Nothing happen!');

}

    然後就可以在使用任何選擇符表示式之後呼叫這個方法了:

    $('div.myclassName').myMehtod();

 

    我們前面提到“當函式需要操作DOM元素時,就是將函式建立為jquery物件方法的好機會”,一個合理的例項方法應包含對它的環境的操作。

11.2.1 物件方法的環境

   在任何外掛方法內部,關鍵字this引用的都是當前的jquery物件。因而,可以在this上面呼叫任何內建的jquery方法,或提取它包含的DOM節點並操作該節點:

   

 

    為了確定如何才能利用物件環境,下面我們來編寫個小外掛,用來操作匹配元素的類。

   

   為了測試這段程式碼是否有效,需要以下html:

   

    樣式表css 如下:

   

方法swapClass中需要解釋的幾個地方:

  • 隱式迭代:要在匹配多個元素的情況下保證行為正確,最簡單的方式就是始終在方法的環境上呼叫.each()方法,這就會執行隱式迭代,而隱式迭代對於維護外掛與內建方法的一致性是至關重要的。
  • 方法連綴:在定義物件方法時,我們必須在所有外掛方法中返回一個jquery物件(除非相應的方法明顯用於取得不同的資訊),以便於能夠正常使用連綴行為。如下面所示:

 11.3 Dom遍歷方法

   在某些情況下,我們定義的外掛方法可能會改變jquery物件引用的DOM元素。

比如,我們想要新增一個查詢匹配元素的祖父級元素的DOM遍歷方法:

解釋下這段程式碼:建立一個新的grandparents陣列,並通過迭代將當前juqery物件引用的全部元素填充這個陣列。然後呼叫.unique()方法去掉填充後的陣列中重複的元素;最後,jquery內建的方法.setArray()把這組元素轉換成新陣列。

 

   為了測試這個方法,定義一個深度巢狀的<div>結構:

 

粗體標示目標元素(<div class="target">
)。使用我們定義的方法,就可以取得目標元素的祖父級的元素了。執行呼叫方法如下:

    然而,我們定義的grandparent方法是有破壞性的。因為呼叫方法作用是突出顯示祖父級元素,然後再隱藏自身,而實際的效果是隱藏了祖父級別的元素,而非自身。

    為了避免這種情況,需要改變我們定義的方法,藉助jquery在內部為每個物件維護的棧,可以做到這一點。

 

這樣,$target就沒有被修改,最初的目標物件將被程式碼隱藏起來。在呼叫此方法時,還可以連綴方法。如:

$(document).ready(function() {
    $('.target').grandparent().andSelf().addClass('highlight');
});

 

11.4  新增新的簡寫方法

    jquery庫必須在方便和複雜之間維持一個微妙的平衡。新增到庫中的每個方法都有助於開發者簡化某些程式碼的編寫,但也會增加基礎程式碼的整體大小並可能影響效能。基於這點考慮,內建功能的許多簡寫方法都移交到外掛中實現,以便開發者可以挑出對某個專案有用的方法,並省略那些無用的方法。

    當我們發現自己在程式碼中需要多次重複使用某個方法時,可能會想到為該方法建立一種簡寫的形式。如,假設我們利用內建的“滑動”和“淡化”技術頻繁為頁面元素新增動畫效果。這兩個效果放到一起意味著同時變換元素的高度和不透明度,而使用.animate()方法可以簡化這兩個操作。

   

   出於完整性考慮,我們的新方法也應該支援與內建的簡寫方法相同的引數。具體來說,應該像.fadeIn()方法一樣那個自定義速度和回撥函式。所以,可以進一步改寫程式碼:

  

    這樣,我們就有了與內建的簡寫方法具有類似功能的自定義的簡寫方法。為了演示這個方法,需要一個簡單的html頁面:

  

 

在按鈕單擊時,指令碼會呼叫我們定義的新方法:

 

而效果也和我們想象的一樣。

 

 

 

continuing...

 

11.5 方法的引數

    下面介紹幾種管理方法引數的技巧。例子:為文字塊新增投影新增外掛方法。

文字塊程式碼如下:

 

     要實現此文字塊(標題)的投影效果,需要編寫一小段程式碼(方法),實現的思路是:對於每個呼叫此方法的元素,都要複製該元素一定數量的副本,調整每個副本的不透明度,再通過絕對定位的方式,以原有元素為基準按照不同的偏移量定位這些副本。

     實現程式碼如下:

    

     呼叫此外掛方法很簡單:

 $(document).ready(function() {
   $('h1').shadow();
 });

 

11.5.1 為方法新增簡單引數

   為了讓使用者使用此方法時,能夠修改副本的相對位移、透明度等,我們需要把這些值定義為方法接受的引數列表。修改後的方法如下:

   呼叫此物件方法:

$(document).ready(function() {
   $('h1').shadow(10, 0.05, -2);
 });

    但這個物件方法還不夠理想,這3個引數容易搞混,它們次序沒有任何規則可循。

11.5.2 引數對映

    作為一種向用戶公開選項的方式,對映顯然要比引數列表更加友好。對映會為每個引數提供一個更有意義的標籤,同時也讓引數次序變得無關緊要,而且,只要有可能通過外掛來模仿jquery API,就應該使用對映來提高一致性和易用性。

  

 呼叫這個方法需要傳遞一個值對映,而不是獨立的各個引數了。

 $(document).ready(function() {
   $('h1').shadow({
     slices: 8,
     opacity: 0.1,
     zIndex: 1
   });
 });

   這樣,只要掃一眼呼叫方法的程式碼,就知道每個引數的作用。

 

11.5.3  預設引數值

    隨著引數的增多,在影射中始終指定每個引數不是必須的。此時,一組合理的預設值可以增強外掛介面的易用性。

在這個方法中,我們定義了一個新的對映defaults,實用函式.extend()可以用接受的選項對映引數來覆蓋defaults中的對應項,並保持選項對映中未指定的預設項不變。

 

   呼叫方法如下:

$(document).ready(function() {
    $('h1').shadow({
     opacity: 0.05 //僅修改透明度值,未指定的引數值為預先定義的預設項值
   });
});

 

$.extend()方法可以接受null值,在使用者可以接受所有預設引數時,我們的方法可以直接執行而不會出錯:

$(document).ready(function() {
    $('h1').shadow();

});

 

11.5.4  回撥函式

    要在方法中使用回撥函式,需要接受一個函式物件作為引數,然後在方法中適當的位置上呼叫該函式。例如:擴充套件前面定義的文字投影方法,讓使用者自定義投影相對於文字的位置。

投影的每個“切片”相對於原始文字都有不同的偏移量。現在,偏移量根據函式sliceOffset()計算出來,使用者可以自定義此函式。呼叫此方法如下:

 $(document).ready(function() {
   $('h1').shadow({
     sliceOffset: function(i) {
       return {x: -i, y: -2*i};
     }//sliceOffset函式
   });//對映引數結束,投影方法結束
 });

 

11.5.5 可定製的預設值

   如果有指令碼多次呼叫我們的外掛,每次呼叫都要傳遞一組不同於預設值的引數,那麼定製預設值就顯得有必要,這樣呼叫時可以減少很多的程式碼的編寫。

   要支援預設值的可定製,需要把它們從方法定義中移出來,放到外部程式碼可以訪問的地方:

 

    由於現在所有對.shadow()的呼叫都要重用defaults對映,因此不能讓$.extend()修改它,我們在此定義一個空對映({})作為$.extend()第一個個引數,讓這個新物件作為被修改的目標。

    於是,使用外掛方法時就可以修改預設值了,修改之後的值可以被所有後續對.shadow()的調研共享,而且,在呼叫方法是仍然可以傳遞選項:

 

11.6  自定義選擇符表示式

   jquery內建的元件也可以擴充套件,與新增新方法不同,我們可以自定義現有的元件。比如一個常見的需求就是自定義jquery提供的選擇符表示式,以便得到更高階的選擇符。

   最簡單的選擇符 表示式是偽類,即以冒號開頭的表示式,如:checked/:nth-child()等。

   下面,我們自定義一個選擇符表示式,:css()偽類,這個選擇符表示式允許我們基於css屬性的數字值查詢元素。

 需要解釋的如下:

  • 以上程式碼告訴jquery,css是一個可以在選擇符表示式中前置冒號的有效字串,當遇到該字串時,應該呼叫給定的函式以確定當前元素是否應該包含在結果集中。
  • element:當前的DOM元素。大多數選擇符都需要這個引數。
  • index:DOM元素在結果集中的索引。這個引數對:eq()和:lt()等選擇符有用。
  • matches:包含解析當前選擇符的正則表示式結果的陣列。通常matches[3]是 這個陣列中唯一有用的項。
  • set:到目前為止匹配的整個DOM元素集合。很少用。

    我們可以通過一下文件演示它的用途:

使用新的選擇符表示式,突出顯示裡表中文字較短的項就很容易了:

$(function() {
    $('div:css(width < 100)').addClass('highlight');
});

 

 

參考《jquery基礎教程》第二版