(翻譯)編寫屬於你的jQuery插件

Writing Your Own jQuery Pluginsjavascript

原文地址:http://blog.teamtreehouse.com/writing-your-own-jquery-pluginscss

jQuery是一個優秀的javascript庫。它不但擁有良好的跨瀏覽器兼容性,容易學習掌握,還能夠垂手可得的爲你的網站添加有趣的交互。同時,大量的jQuery插件可以讓你爲所欲爲的完成你想要完成的工做。java

然而在日常的工做中,並非總可以找到能夠徹底知足需求的插件,或者你想要將一些經常使用的功能封裝以便保證項目的可重用性。在這些情形下,編寫本身的jQuery插件是一個很好的知足需求的手段。jquery

其實,編寫jQuery插件並無想像中難。這篇文章,咱們將經過編寫一個簡單的插件,爲其添加一些參數和事件回調,來向你完整的展現整個流程。git

準備工做

像大多數編程指南的開篇同樣,咱們也以一個「Hello World」插件開始吧。在開始以前,先建立必要的文件並在HTML文檔中引用它們。首先,在站點的js目錄下新建插件文件jquery.hello-world.js。一般,jQuery插件的命名以「jquery.」開始。github

接下來,須要在HTML文件中連接插件文件及其依賴的jquery核心庫。咱們將如下兩行放置在文檔的底部,也即</body>標籤以前。編程

<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/jquery.hello-world.js"></script>

jQuery插件的結構

jQuery自己已經爲插件開發提供了足夠的支持。但咱們依然須要遵循JavaScript開發的最佳實踐,將全部的代碼都囊括在一個本地做用域中。下面是一個常規的jQuery插件基礎結構:瀏覽器

(function($) {
    $.fn.helloWorld = function() {

        // Future home of "Hello, World!"

    }
}(jQuery));

 

讓咱們花一點時間來理解一下上述代碼的含義。經過將全部代碼包含在 (function() {}) 自執行代碼塊中,可以保證插件內部的全部變量不會污染到全局變量。畢竟,咱們確定不肯意看到編寫的插件和頁面中的其它JavaScript代碼發生衝突。函數

可能你已經注意到,咱們定義插件的方式,就好像jQuery也位於其「無衝突」模式。再一次強調,咱們須要避免插件與頁面中其它JavaScript發生衝突,這也包括使用到的'$'符號。該符號頗有可能被其它的JavaScript庫使用。學習

最後,$.fn這種寫法是jQuery定義插件的方式。這裏將其命名爲helloWorld並將全部代碼放置在該函數中。下面,讓咱們作一些真正有意義的工做。

插件代碼編寫

爲了使插件的代碼儘量的簡單,同時又能達到演示的目的,咱們將要完成的功能是改變關聯的元素的文本內容爲「hello world」。這已經近乎於傻瓜式的操做了。

(function($) {

    $.fn.helloWorld = function() {

        this.each( function() {
            $(this).text("Hello, World!");
        });

    }

}(jQuery));

 

當在jQuery選擇器上調用上述插件時,關聯的元素已是一個jQuery對象,所以再也不須要再用"$(this)"結構進行包裝。然而,若是須要在一個循環中使用每個匹配的元素,好比$.each(),則通常會使用$(this)對循環的元素進行包裝。

假如咱們想要改變下面頁面中全部的<h2>標題的文本:

調用的方式你已經很熟悉了,就像這樣:

<script>
$(document).ready( function() {
    $('h2').helloWorld();
});
</script>

結果爲:

 

咱們能作的遠遠不止如此。當上面的插件調用時,實際上徹底被隔離在了它自己的做用域。也就是說,調用的做用鏈在插件內部被終止了。若是你試着以jQuery的鏈式寫法調用其它操做時,是不會生效的。爲了修復這個問題,須要確保返回每一個DOM元素循環後的結果:

(function($) {

    $.fn.helloWorld = function() {

        return this.each( function() {
            $(this).text("Hello, World!");
        });

    }

}(jQuery));

 

恭喜你,已經寫出了你人生中的第一個jQuery插件!

稍安勿躁,好戲在後頭!

如今你可能正沉浸在編寫出本身的jQuery插件的喜悅中,這時候你的老大跑過來講,想要把如今的網站翻譯成西班牙語。老天爺,如今該咋整?

其實,能夠簡單的添加一個參數完成上述需求。從新審視上述插件的代碼,咱們能夠替換其內部的硬編碼文本內容爲一個變量,在調用的時候傳入該變量的值。

(function($) {

    $.fn.helloWorld = function( customText ) {

        return this.each( function() {
            $(this).text( customText );
        });

    }

}(jQuery));

 

如你所見,在調用的時候能夠傳入任何想要傳入的文本值。辦公室的馬德里先生已經將咱們須要的東西翻譯成了西班牙語,如今可使用參數的方式調用該插件:

<script>
$(document).ready( function() {
    $('h2').helloWorld('¡Hola, mundo!');
});
</script>

頁面呈現以下:

徹底自由的控制

可能你已經感受到一點擔心,若是在調用插件的時候沒有傳入文本怎麼辦?顯而易見,頁面中匹配的元素的文本會被插件修改成空值,這可能不是咱們預期的結果。另外,咱們的老大已經跑過來要求添加一個變量,若是他再跑過來要求添加更多的可定製化的選項怎麼辦?不斷的添加參數畢竟不是長遠之計,一勞永逸的解決方法是經過options對象。

咱們已經知道具體的文本內容須要由外部傳入,如今,老大又要求文本顏色和字體大小一樣在調用時指定(好吧,我知道顏色和字體大小均可以經過jQuery內置的函數進行控制,這裏僅僅是一個演示)。讓咱們爲插件添加一個options參數對象,同時經過$.extend方法與默認的參數進行合併:

(function($) {

    $.fn.helloWorld = function( options ) {

        // Establish our default settings
        var settings = $.extend({
            text         : 'Hello, World!',
            color        : null,
            fontStyle    : null
        }, options);

        return this.each( function() {
            // We'll get back to this in a moment
        });

    }

}(jQuery));

如今咱們有了可供外部設置的選項。若是調用的時候缺乏了待替換的文本,將會使用指定的默認值。另外,在配置參數中添加了"color"和"fontStyle"兩個屬性,默認值均爲"null"。若是在CSS文件中已經定義了顏色值和字體大小,在插件調用時不須要再重複指定。固然,兩者都可以在插件內部重寫。代碼以下:

return this.each( function() {
    $(this).text( settings.text );

    if ( settings.color ) {
        $(this).css( 'color', settings.color );
    }

    if ( settings.fontStyle ) {
        $(this).css( 'font-style', settings.fontStyle );
    }
});

由於該插件的目的是替換文本。若是提供的文本值爲空則沒有任何意義,這也是在插件內部爲其指定默認值的緣由,當參數缺失時顯示缺省值總比空白要好得多。另外一方面,顏色值和字體風格則只須要提供一個可供重寫的入口。

這時候老大跑過來講想要將站點翻譯爲法語,另外還但願將文本顏色改成藍色,字體調整爲italic。幸運的是,咱們的插件處理這些需求毫無壓力:

$('h2').helloWorld({
    text        : 'Salut, le monde!',
    color       : '#005dff',
    fontStyle   : 'italic'
});

你看,咱們的插件已經擁有了一些由外部控制的參數。未來能夠在不影響現有調用的基礎上,很是容易的添加或去掉某個參數。這些都益於良好的可擴展性。

但咱們的老大帶着另一個需求再一次跑了過來:一旦插件按其預約的方式調用完畢,應該彈出一個對話框通知用戶這個消息。爲了達到這個目的,有兩個選擇:要麼辭職,由於這個傢伙明顯無視最初的需求文檔。要麼不走這麼極端的路線,爲咱們的插件添加處理回調函數的能力。

回調函數是JavaScript函數的參數,同時它自己也是一個JavaScript函數。其並非jQuery獨有的特性。初看上去回調函數是一個複雜的概念,但實際它的使用很是簡單。

咱們須要作的僅僅是在配置對象中附加一個額外的參數:

// Establish our default settings
var settings = $.extend({
    text         : 'Hello, World!',
    color        : null,
    fontStyle    : null,
    complete     : null
}, options);

如今,當插件調用完畢時,就該附加的「complete」參數生效了。爲了調用該參數,首先須要確保其是一個真正的函數。幸運的是,jQuery已經內置了$.isFunction函數幫助咱們完成這個檢測:

return this.each( function() {
    // Our plugin so far

    if ( $.isFunction( settings.complete ) ) {
        settings.complete.call( this );
    }
});

頁面中調用以下:

$('h2').helloWorld({
    text        : 'Salut, le monde!',
    color       : '#005dff',
    fontStyle   : 'italic',
    complete    : function() { alert( 'Done!' ) }
});

最終的效果,插件執行完畢後會觸發回調函數:

結語

當你一遍又一遍的寫着大量重複的JavaScript代碼,自定義jQuery插件是一種很好擺脫這種泥沼的方式。經過自定義插件,你在保持本身代碼DRY(dont repeat yourself)的同時,也確保了全局名稱空間的獨立和純度。

若是你想調試上述示例代碼,能夠在個人 GitHub 獲取。

相關文章
相關標籤/搜索