• JQuery Plugin 开发


    学习 JQuery 插件开发之后, 可以将自己平时常用的功能封装成插件, 便于在不同的项目之间使用.

    JQuery 官网上的 插件开发教程就很不错, 简单易懂.

    jquery 中有2个重要的API是和插件编写相关的.

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

    这2个API都是为了将自己编写的功能以插件的形式加入到 jquery 中.

    但是含义上是有区别的.

    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 {
                 500px;
                height:100px;
              }
    
              .smalldiv {
                   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
  • 相关阅读:
    滚动 冻结 div demo
    JavaScript去除字符串两边空格trim
    window.showModalDialog以及window.open用法简介
    转: 分享我创业4年失败的经历
    [转]JavaScript break跳出多重循环
    showModalDialog 传值及刷新
    防止文字撑开表格,强制表格大小
    带记忆功能的表单
    checkbox 全选
    asp教程:关于jquery跨域彻底的解决方法
  • 原文地址:https://www.cnblogs.com/hubl/p/5760300.html
Copyright © 2020-2023  润新知