1. 程式人生 > >jquery外掛編寫學習小結

jquery外掛編寫學習小結

編寫外掛的目的是給已經有的一系列方法或函式做一個封裝,以便在其他地方重複使用,方便後期維護和提高開發效率。
這裡寫圖片描述
一、外掛的種類
jQuery的外掛主要分為3種類型。
1、封裝物件方法的外掛
2、封裝全域性函式的外掛
3、選擇器外掛
這裡我們主要討論第一種外掛的開發流程。
封裝物件方法的外掛:
這種外掛是將物件方法封裝起來,用於對通過選擇器獲取的jQuery物件進行操作,是最常見的一種外掛,有95%以上的外掛都是這種型別的外掛。

二、外掛的基本要點
1、所有物件方法都應當附加到jQuery.fn上,而所有全域性函式都應當附加到jQuery物件本身上。
2、在外掛內部,this指向的是當前通過選擇器獲取的jQuery物件,而不是DOM元素。
3、所有方法或函式外掛,都應當以分號結尾,為了更穩妥些,甚至可以再外掛頭部也加上一個分號,以免他們的不規範程式碼給外掛帶來影響。
4、外掛應當返回一個jQuery物件,以保證鏈式操作。
5、閉包的使用。

三、外掛中的閉包
閉包:簡單來說,當一個內部函式在包含他們的外部函式之外被呼叫時,就會形成閉包。
利用閉包的特性,既可以避免內部臨時變數影響到全域性空間,又可以在外掛內部繼續使用$作為jQuery的別名。常見的jQuery外掛都是這樣的形式:

;(function ($) {
    //...
 })(jQuery);

再看看這段程式碼:

;(function ($) {
    //定義一個區域性變數foo,僅函式內部可以訪問,外部無法訪問
    var foo;
    var bar = function(){
        //...
    }
    //下面這句話相當於增加了一個jQuery物件上的全域性函式BAR。可以通過$.BAR()的方式來訪問內部定義的函式bar(),並且內部函式bar()也能訪問foo
$.BAR = bar; })(jQuery);

其實這裡與我之前寫的一篇介紹模組化程式設計的博文很相似,都用到了閉包的蓋概念,不過在模組化程式設計中通過閉包可以拓展模組方法,而這裡是增加$物件上的方法,也就是jQuery全域性函式外掛。

四、jQuery.extend()方法
jQuery提供了兩個用於擴充套件jQuery功能的方法,即jQuery.fn.extend方法和jQuery.extend()方法。前者用於可擴充套件之前提到的三種類型外掛中的第一種,後者用於擴充套件後兩種外掛。這裡要介紹的是jQuery.extend()方法除了可以用於擴充套件jQuery物件之外,還有一個很強大的功能,就是用於擴充套件已有的Object物件。

jQuery.extend(target,obj1,obj2,...objn);

用一個或多個物件來擴充套件一個物件,然後返回被擴充套件的物件。
舉個栗子:

var settings = { validate: false,limit: 5,name: "foo" };
var options= { validate: true,name: "bar" };
var newOptions = jQuery.extend(settings,options);

結果為:

newOptions = { validate: true,limit: 5,name: "bar" };

顯然,這個方法的特性可以很方便的用傳入的引數來覆蓋預設值,在外掛的編寫中會經常用到。

五、編寫jQuery外掛
鑑於之前在實習期間(採遺網電商平臺)寫個人中心欄目時經常會遇到各種各樣的表格,為了避免重複的工作,遂學習寫了一個具有表格隔行變色、點選選中變色簡單功能的外掛。
不然每次都需要重複下面類似程式碼:

$("tbody>tr:odd").addClass("odd");
$("tbody>tr:even").addClass("even");
$("tbody>tr:has(:checked)").addClass("selected");
$("tbody>tr").click(function () {
    var hasSelected = $(this).hasClass("selected");
    $(this)[hasSelected?"removeClass":"addClass"]  ("selected").find(':checkbox').prop('checked',!hasSelected);
});

功能不大,但也算是瞭解了外掛的具體開發流程。
首先,我們建立一個新的檔案jquery.tableBgColor.js,把外掛方法取名tableBgColor,然後搭好框架:

;(function ($) {
        $.fn.extend({
            "tableBgColor":function(options){
                    //設定預設值
                    options= $.extend({
                        odd:"odd",
                        even:"even",
                        selected:"selected"
                    },options);

                    //...外掛程式碼

                    return this;//返回jQuery物件,保證鏈式操作
                })
            }
        });

})(jQuery);

現在,我們的目的應該是使用選擇器選擇某個表格,執行tableBgColor()方法後,將對應表格內的tr元素都進行各行變色,並且點選某一行之後也會變色,並且選中對應行內的checkbox。
因此,只需將之前會重複的程式碼稍作修改放入框架中:

;(function ($) {
        $.fn.extend({
            "tableBgColor":function(options){
                //each()方法遍歷匹配元素,因為可能匹配的元素不止一個
                return this.each(function () {
                    //設定預設值
                    options= $.extend({
                        odd:"odd",
                        even:"even",
                        selected:"selected"
                    },options);

                    $("tbody>tr:odd",this).addClass(options.odd);
                    $("tbody>tr:even",this).addClass(options.even);
                    $("tbody>tr:has(:checked)",this).addClass("selected");
                    $("tbody>tr",this).click(function () {
                        var hasSelected = $(this).hasClass(options.selected);
                        $(this)[hasSelected?"removeClass":"addClass"](options.selected).find(':checkbox').prop('checked',!hasSelected);//注意這裡用的是prop而不是attr
                    });

                    return this;
                })
            }
        });

})(jQuery);

此時,外掛就完成了,現在來測試這個外掛。構造表格,id為test_table:

<table width="100%" style="table-layout: fixed" id="test_table">
    //...此處省略
</table>

設定相應的CSS類:

        table{
            text-align: left;
            border-spacing: 0;
            border-collapse: collapse;
        }
        td,th{
            border: 1px solid #e2e2e2;
            padding: 3px;
        }
        th{
            background-color: #1B6540;
            color: #fff;
        }
        .odd{
            background-color: #4FA46B;
        }
        .even{
            background-color: #8ECE9F;
        }
        .selected{
            background-color: #ecb6c4;
        }

引入外掛檔案:

<script src="jquery.min.js"></script>
<script src="jquery.tableBgColor.js"></script>

呼叫外掛方法:

    $(function () {
        $("#test_table").tableBgColor();
    })

得到如下效果:
這裡寫圖片描述
點選某一行:
這裡寫圖片描述
檢查連試操作功能:

$("#test_table").tableBgColor().find("th").css("background-color","red");

頭部變為紅色:
這裡寫圖片描述
大功告成,完美!
現在你可能會覺得有點小缺陷,外掛裡沒有寫到如何解決衝突(conflict)問題,解決這個問題並不難,只需將之前的程式碼更改如下:

;(function ($) {
        var old = $.fn.tableBgColor;//先將之前的即將被覆蓋的方法儲存在old中

        //注意,換了一種定義外掛的方法,以便後面$.fn.tableBgColor.noConflict能正常呼叫tableBgColor方法
        $.fn.tableBgColor = function(options){
                return this.each(function () {
                    //設定預設值
                    options= $.extend({
                        odd:"odd",
                        even:"even",
                        selected:"selected"
                    },options);

                    $("tbody>tr:odd",this).addClass(options.odd);
                    $("tbody>tr:even",this).addClass(options.even);
                    $("tbody>tr:has(:checked)",this).addClass("selected");
                    $("tbody>tr",this).click(function () {
                        var hasSelected = $(this).hasClass(options.selected);
                        $(this)[hasSelected?"removeClass":"addClass"](options.selected).find(':checkbox').prop('checked',!hasSelected);
                    });
                    return this;
                })
            }
        //定義tableBgColor物件的noConflict方法,使得執行這個方法後tableBgColor方法會還原成之前old中所保留的方法
        $.fn.tableBgColor.noConflict = function(){
            $.fn.tableBgColor = old;
            return this;
        }
})(jQuery);

你可能還會覺得有點小瑕疵,該表格還無法進行全選功能,當然也可以自己再動手寫一個全選功能的外掛,不過需要注意的是全選功能涉及到的元素可能較多,在進行html結構設計的時候最好配合外掛的功能編寫,這裡就不再多說。