JQuery Plugin 開發

學習 JQuery 插件開發以後, 能夠將本身平時經常使用的功能封裝成插件, 便於在不一樣的項目之間使用.javascript

JQuery 官網上的 插件開發教程就很不錯, 簡單易懂.css

參考網址:html

  1. http://learn.jquery.com/plugins/basic-plugin-creation/
  2. http://learn.jquery.com/plugins/advanced-plugin-concepts/

 

本文就是基於官網上的教程整理的, 也加入了本身實驗的一些示例。java

 

1. 插件編寫相關函數

jquery 中有2個重要的API是和插件編寫相關的.jquery

  1. jQuery.extend(object)    即 $.extend(object)
  2. jQuery.fn.extend(object) 即 $.fn.extend(object)

 

這2個API都是爲了將本身編寫的功能以插件的形式加入到 jquery 中.chrome

可是含義上是有區別的.json

 

1.1 $.extend(object)

這個函數是用來擴展 jQuery 自己, 也就是擴展 "$" 的.閉包

示例以下:函數

<!DOCTYPE HTML>
<html>
    <head>
        <title>jquery plugin test</title>
        <script type="text/javascript" src="js/jquery-1.11.1.js"></script>
        <script type="text/javascript">
          $(function(){
              
              $("#btn-extend").click(function(){
                  $.extend({
                      test: function(a) { alert(a); },
                  });
              });

              $("#btn-test").click(function(){
                  if ($.test)
                      $.test("test");
                  else
                      alert("不存在 $.test 方法!");
              });
          });
        </script>
    </head>
    <body>
        <button id="btn-test">測試 $.test() </button>
        <button id="btn-extend">擴展 $ 自己 </button>
    </body>
</html>

 

首先點擊 [btn-test] 按鈕, 提示沒有 test 方法, 而後點擊 [btn-extend] 按鈕, 擴展 $ 自己.學習

再次點擊 [btn-test] 按鈕, 執行擴展的 $.test() 函數.

 

1.2 $.fn.extend(object)

這個函數用來爲 jQuery 對象提供新的方法.

所謂 jQuery 對象, 最多見的咱們平時經過jQuery選擇器獲取的對象, 好比: $("#id"), $(".class") 等等.

<!DOCTYPE HTML>
<html>
    <head>
        <title>jquery plugin test</title>
        <script type="text/javascript" src="js/jquery-1.11.1.js"></script>
        <script type="text/javascript">
          $(function(){
              
              $("#btn-extend").click(function(){
                  $.fn.extend({
                      test: function(a) { alert(a); },
                  });
              });

              $("#btn-test").click(function(){
                  if ($(this).test)
                      $(this).test($(this).attr("id"));
                  else
                      alert("不存在 test 方法!");
              });
          });
        </script>
    </head>
    <body>
        <button id="btn-test">測試 $(this).test() </button>
        <button id="btn-extend">擴展 jQuery($) 對象 </button>
        
    </body>
</html>

首先點擊 [btn-test] 按鈕, 提示沒有 test 方法, 而後點擊 [btn-extend] 按鈕, 擴展 $ 對象.

再次點擊 [btn-test] 按鈕, 執行擴展的 $.fn.test() 函數.

 

編寫 jQuery 插件以前, 必定要弄懂 "$ 自己" 和 "$ 對象" 的區別. ($ 就是 jQuery)

也就是弄懂 $.extend 和 $.fn.extend 之間的區別.

 

2. UI相關的插件

通常來講, 純UI相關的插件不多, 都是UI和功能一塊兒配合使用的, 好比 jQuery UI 庫.

下面的示例主要爲了說明如何使用 jQuery 插件, 因此只和UI相關.

 

2.1 示例1 : 統一設置顏色

示例 HTML:

<!DOCTYPE HTML>
<html>
    <head>
        <title>jquery plugin test</title>
        <script type="text/javascript" src="js/jquery-1.11.1.js"></script>
        <script type="text/javascript" src="js/jquery-plugin.js"></script>
        <script type="text/javascript">
          $(function(){
              $("#btn-plugin").click(function(){
                  $(".smalldiv").toggle_back();
              });
          });

        </script>
        <style type="text/css" media="screen">
            
          .bigdiv {
            width: 500px;
            height:100px;
          }

          .smalldiv {
              width: 50px;
              height: 50px;
              background-color: green;
              float:left;
          }
        </style>
    </head>
    <body>
        <button id="btn-plugin">執行插件</button>
        <div class="bigdiv">
            <div class="smalldiv red">
                1
            </div>
            <div class="smalldiv green">
                2
            </div>
            <div class="smalldiv red">
                3
            </div>
            <div class="smalldiv green">
                4
            </div>
            <div class="smalldiv red">
                5
            </div>
            <div class="smalldiv green">
                6
            </div>
            <div class="smalldiv red">
                7
            </div>
            <div class="smalldiv green">
                8
            </div>
            <div class="smalldiv red">
                9
            </div>
            <div class="smalldiv green">
                10
            </div>
        </div>
        
    </body>
</html>

 

示例 jQuery 插件:

/* jquery plugin for test
 * filename: jquery-plugin.js
 */

// 下面的格式也是 jQuery 插件的經常使用寫法
(function ($) {
    $.fn.toggle_back = function() {
        if (this.css("background-color") == "rgb(255, 0, 0)")
            this.css("background-color", "green");
        else
            this.css("background-color", "red");
    };
}(jQuery));

經過點擊 html 頁面上的按鈕, 能夠切換全部 smalldiv 的背景色.

 

2.2 示例2 : 分別設置顏色

這個例子比上面那個略微複雜一些, 上面的示例1 是對全部 smalldiv 統一設置背景色, 不夠靈活.

這個示例經過 jQuery 的 $.fn.each 函數根據每一個 smalldiv 的 class 分別設置背景色.

(HTML部分的代碼和示例1 同樣)

/* jquery plugin for test
 * filename: jquery-plugin.js
 */

// 下面的格式也是 jQuery 插件的經常使用寫法
(function ($) {
    $.fn.toggle_back = function() {
        this.each(function() {
            var div = $(this);
            if (div.hasClass("red")) {
                div.removeClass("red");
                div.addClass("green");
                div.css("background-color", "green");
            }
            else {
                div.removeClass("green");
                div.addClass("red");
                div.css("background-color", "red");
            }
        });
        return this;
    };
}(jQuery));

 

這裏須要注意2個地方:

1. 代碼中 this 的含義

this.each(function() {

這裏的 this 是jQuery 對象, 也就是經過 $("#id"), $(".class") 之類的選擇器獲取的對象.

*注意* 這個 this 的位置是在 $.fn.toggle_back 的主函數體中.

 

var div = $(this);

這裏的 this 是 DOM 對象, 因此經過 $(this) 才能變成 jQuery 對象.

至於爲何 each 中的this就是各個 DOM 對象, 那是由於 each 的實現中將 jQuery 對象轉換爲了 DOM 對象.

 

2. 插件代碼最後的 return this;

這裏之因此要 return this; 是爲了實現 jQuery 的鏈式表達式. 也就是 return this; 以後, 能夠接着調用其餘 jQuery 函數.

好比 $(".class").toggle_back().css("color", "red");

上面的示例2中 $("#btn-plugin").click 函數能夠改成以下:

$("#btn-plugin").click(function(){
     $(".smalldiv").toggle_back().css("color", "red");
});

 

3. 功能型插件

下面經過一個 日期轉換 的例子, 說明功能型插件的寫法.

HTML 部分:

<!DOCTYPE HTML>
<html>
    <head>
        <title>jquery plugin test</title>
        <script type="text/javascript" src="js/jquery-1.11.1.js"></script>
        <script type="text/javascript" src="js/jquery-plugin.js"></script>
        <script type="text/javascript">
          $(function(){
              $("#btn-plugin").click(function(){
                  $("h2").dt_format(new Date());
              });
          });

        </script>
    </head>
    <body>
        <button id="btn-plugin">顯示格式化的時間</button>
        <hr />
        <h1>當前時間:</h1>
        <h2 class="date">nothing</h2>
        <h2 class="time">nothing</h2>
        <h2 class="datetime">nothing</h2>
    </body>
</html>

 

插件 js 只是簡單的轉換了一時間格式, 僅僅爲了演示:

/* jquery plugin for test
 * filename: jquery-plugin.js
 */

(function ($) {

    $.fn.dt_format = function(dt) {
        this.each(function(){
            var elem = $(this);
            if (elem.hasClass("date"))
                elem.text($.fn.dt_format.date(dt));
            if (elem.hasClass("time"))
                elem.text($.fn.dt_format.time(dt));
            if (elem.hasClass("datetime"))
                elem.text($.fn.dt_format.datetime(dt));
        });
        return this;
    };

    $.fn.dt_format.date = function(dt) {
        var year = dt.getFullYear();
        var month = dt.getMonth() + 1;
        var day = dt.getDate();
        return year + "年/" + month + "月/" + day + "日";
    };

    $.fn.dt_format.time = function(dt) {
        var hour = dt.getHours();
        var minute = dt.getMinutes();
        var second = dt.getSeconds();
        return hour + "時:" + minute + "分:" + second + "秒";
    };

    $.fn.dt_format.datetime = function(dt) {
        return $.fn.dt_format.date(dt) + " " + $.fn.dt_format.time(dt);        
    };
}(jQuery));

點擊HTML頁面上的按鈕, 分別轉換出不一樣的時間格式並顯示在頁面上.

 

4. 插件的默認參數

上面的插件須要一個參數, 若是調用插件時沒有帶參數, 則致使js錯誤.

爲了更好的用戶體驗, 下面給插件加入默認參數(也就是當前時間).

新的 plugin js以下:

/* jquery plugin for test
 * filename: jquery-plugin.js
 */

(function ($) {

    $.fn.dt_format = function(options) {

        // 將用戶的options 和 默認參數defaults 合併, 若有重複, 優先使用 options
        // 這裏的 $.extend 的第一個參數是空的對象, 緣由後面解釋
        var settings = $.extend({}, $.fn.dt_format.defaults, options);
        
        this.each(function(){
            var elem = $(this);
            if (elem.hasClass("date"))
                elem.text($.fn.dt_format.date(settings.dt));
            if (elem.hasClass("time"))
                elem.text($.fn.dt_format.time(settings.dt));
            if (elem.hasClass("datetime"))
                elem.text($.fn.dt_format.datetime(settings.dt));
        });
        return this;
    };

    // 這裏提供默認參數
    $.fn.dt_format.defaults = {
        dt: new Date(),
    };

    $.fn.dt_format.date = function(dt) {
        var year = dt.getFullYear();
        var month = dt.getMonth() + 1;
        var day = dt.getDate();
        return year + "年/" + month + "月/" + day + "日";
    };

    $.fn.dt_format.time = function(dt) {
        var hour = dt.getHours();
        var minute = dt.getMinutes();
        var second = dt.getSeconds();
        return hour + "時:" + minute + "分:" + second + "秒";
    };

    $.fn.dt_format.datetime = function(dt) {
        return $.fn.dt_format.date(dt) + " " + $.fn.dt_format.time(dt);        
    };
}(jQuery));

 

HTML中調用插件時能夠不用參數了

$(function(){
    $("#btn-plugin").click(function(){
        $("h2").dt_format(); // 這裏能夠不輸入參數, 使用默認參數.
    });
});

 

補充: 合併參數時, 使用了 $.extend, 這個方法的做用是將全部參數 合併成一個大的json對象, 有相同的key時, 後面的參數覆蓋前面的參數.

$.extend 的第一個參數是 {}, 之因此這樣, 是由於合併後, 會破壞第一個參數, 因此不能將 defaults 放在第一個.

說明示例以下: (用chrome的console窗口能夠看到輸出結果)

<!DOCTYPE HTML>
<html>
    <head>
        <title>jquery plugin test</title>
        <script type="text/javascript" src="js/jquery-1.11.1.js"></script>
        <script type="text/javascript">
          $(function(){
              var defaults = { "id": 1, "name": "test"};
              var options = { "sex": "man", "name": "test2" };
              console.log("合併前, 各個參數以下:");
              console.log(defaults);
              console.log(options);
              console.log("合併後, 各個參數以下:");
              $.extend(defaults, options);
              console.log(defaults); // 這裏能夠發現 defaults中的內容是 defaults和options合併後的結果
              console.log(options);
          });

        </script>
    </head>
    <body>
    </body>
</html>

 

5. 插件中的公有及私有函數

雖然 javascript 不是純粹的面向對象的語言, 可是經過其強大的閉包功能, 也能構造出相似其餘面嚮對象語言的公有/私有函數.

*功能型插件* 中的示例中3個函數 $.fn.dt_format.date, $.fn.dt_format.time, $.fn.dt_format.datetime 都是公有函數, 能夠被插件使用者所覆蓋.

好比, 將上面示例的HTML改成以下: (覆蓋了插件中的 $.fn.dt_format.datetime 方法)

<!DOCTYPE HTML>
<html>
    <head>
        <title>jquery plugin test</title>
        <script type="text/javascript" src="js/jquery-1.11.1.js"></script>
        <script type="text/javascript" src="js/jquery-plugin.js"></script>
        <script type="text/javascript">
          $(function(){
              $("#btn-plugin").click(function(){
                  $("h2").dt_format();
              });
          });

          $.fn.dt_format.datetime = function(dt) {
              alert("覆蓋公有函數");
          };
        </script>
    </head>
    <body>
        <button id="btn-plugin">顯示格式化的時間</button>
        <hr />
        <h1>當前時間:</h1>
        <h2 class="date">nothing</h2>
        <h2 class="time">nothing</h2>
        <h2 class="datetime">nothing</h2>
    </body>
</html>

 

若是不想公開方法, 改變那3個函數定義方法便可:

/* jquery plugin for test
 * filename: jquery-plugin.js
 */

(function ($) {

    $.fn.dt_format = function(options) {

        var settings = $.extend({}, $.fn.dt_format.defaults, options);
        
        this.each(function(){
            var elem = $(this);
            if (elem.hasClass("date"))
                elem.text(date(settings.dt));
            if (elem.hasClass("time"))
                elem.text(time(settings.dt));
            if (elem.hasClass("datetime"))
                elem.text(datetime(settings.dt));
        });
        return this;
    };

    $.fn.dt_format.defaults = {
        dt: new Date(),
    };

    var date = function(dt) {
        var year = dt.getFullYear();
        var month = dt.getMonth() + 1;
        var day = dt.getDate();
        return year + "年/" + month + "月/" + day + "日";
    };

    var time = function(dt) {
        var hour = dt.getHours();
        var minute = dt.getMinutes();
        var second = dt.getSeconds();
        return hour + "時:" + minute + "分:" + second + "秒";
    };

    var datetime = function(dt) {
        return date(dt) + " " + time(dt);        
    };
}(jQuery));

這樣, 插件使用者就不能覆蓋 date, time, datetime 方法了.

 

6. 插件編寫的注意點

是從 jQuery 官方網站的插件教程中總結出來的:

  1. 不要自定義語法
  2. 不要寫死元素的id或者class, 將其以 options 的形式開放出來
  3. 提供 callback
相關文章
相關標籤/搜索