zoukankan      html  css  js  c++  java
  • jquery扩展以及jquery ui插件开发

    1. 在jquery命名空间添加全局函数,与普通类添加全局函数一样,定义一个立即调用函数表达式,接受jQuery作为参数并将参数命名为$保证在jQuery.noConflict()调用的情况下也能在内部使用$
       1 (function ($) {
       2   $.sum = function (array)
       3   {
       4     var total = 0;
       5     $.each(array, function (index, value) {
       6       value = parseFloat(value) || 0;
       7       total += value;
       8     });
       9     return total;
      10   }; // end sum()
      11   
      12   $.average = function (array)
      13   {
      14     if ($.siArray(array))
      15     {
      16       return $.sum(array) / array.length;
      17     } // end if
      18     return "";
      19   }; // end average()
      20 }(jQuery));
      21 
      22 var data = [3, 4, 3, 4, 3, 4, 3, 4];
      23 console.log("sum: " + $.sum(data)); // 28
      24 console.log("avreage: " + $.average(data)); // 3.5
    2. 为jQuery对象添加方法,与普通类添加对象方法一样,
      1. 普通类通过默认为prototype添加方法,jQuery的prototype起了个简单的名字:fn,
      2. 函数调用上下文this为当前调用该方法的jQuery对象,
      3. 为适当方法返回this可支持链式调用
      4. 方法采用对象式传递更加方便
      5. 为方法设置可配置默认参数
      6. 下面是一个例子,用来说明基本思路,功能实现方法不推荐用于实际开发
         1 (function ($) {
         2   $.fn.shadow = function (opts)
         3   {
         4     var options = $.extend({}, $.fn.shadow.defaults, opts);
         5     return this.each(function () {
         6       var $originalelement = $(this);
         7       for (var i = 0; i < options.copies; ++i)
         8       {
         9         var offset = options.copyOffset(i);
        10         $originalElement.clone()
        11           .css({
        12             position: "absolute",
        13             left: $originalElement.offset().left + offset.x,
        14             top: $originalElement.offset().top + offset.y,
        15             margin: 0,
        16             zIndex: -1,
        17             opacity: options.opacity
        18           }).appendTo("body");
        19       } // end for
        20     }); // end each()
        21   }; // end shadow()
        22   
        23   // define comfigurable defaults for shadow
        24   $.fn.shadow.defaults = {
        25     copies: 5,
        26     opacity: 0.1,
        27     copyOffset: function (index)
        28     {
        29       return {x: index, y: index};
        30     } // end copyOffset()
        31   }; // end defaults
        32 }(jQuery));
        33 
        34 
        35 // test case
        36 $.fn.shadow.defaults.copies = 10;
        37 $("h1").shadow({
        38   copyOffset: function (index)
        39   {
        40     return {x: -index, y: index};
        41   } // end copyOffset()
        42 });
    3. jquery ui插件开发比扩展jquery稍微复杂,但是jQuery UI包含了一个控件工厂$.widget()帮我们做了很多工作,通过这个工厂方法可以保证我们的代码遵守API标准,也就方便用户使用
      1. 插件具有stateful特性,这样可以通过检查状态,修改状态完成各种需求
      2. 用户选项和可配置默认选项自动归并
      3. 多个插件方法可以通过传递字符串为方法调用简单jQuery方法实现无缝连接,
      4. 自定义事件监控可以访问控件实例的数据
    4. jQuery UI插件通过调用$.widget()创建。这个函数接受两个参数
      1. 第一个是一个字符串,这是一个包含了命名空间的插件名如"ljq.tooltip"这样我们的插件就可以通过在jQuery对象上调用.tooltip()来安装了
      2. 第二个参数是一个对象,其属性包含一些widget()预定义属性,根据约定完成空间初始化、销毁等
    5. 为第二个参数设置_create,这是在插件初始化时控件工厂自动调用的函数:
       1 (function ($) {
       2   $.widget("ljq.tooltip", {
       3     _create: function ()
       4     {
       5       this._tooltipDiv = $("<div></div>")
       6         .addClass("ljq-tooltip-text ui-widget "
       7           + "ui-state-highlight ui-corner-all")
       8         .hide().appendTo("body");
       9       this.element.addClass("ljq-tooltip-trigger")
      10         .on("mouseenter.ljq-tooltip", $.proxy(this._open, this))
      11         .on("mouseleave.ljq-tooltip", $.proxy(this._close, this));
      12     }, // end _create()
      13     _open: function ()
      14     {
      15       var elementOffset = this.element.offset();
      16       this._tooltipDiv.css({
      17         position: "absolute",
      18         left: elementOffset.left,
      19         top: elementOffset.top + this.element.height()
      20       }).text(this.element.data("tooltip-text"));
      21       this._tooltipDiv.show();
      22     }, // end _open()
      23     _close: function ()
      24     {
      25       this._tooltipDiv.hide();
      26     } // end _close()
      27   }); // end widget.toolip()
      28 }(jQuery));
      1. 其中_create()调用上下文this为当前创建的控件实例,可以给它添加所需的属性,例如:this._tooltipDiv
      2. 控件实例包含一些有用的属性: this.element是创建空间的jQuery对象
      3. 通过为this.element绑定mouseenter和mouseleave事件监听器,控制tooltip的出现
    6. 销毁控件,上面的方法创建了一个jQuery新方法,在jQuery对象上调用即可创建tooltip,如$("a").tooltip(),同样也可以通过传入一个字符串作为参数,用于指定需要调用的方法,其中内建的destroy方法会将控件取消,.tooltip("destroy")可以调用,控件工厂可以帮我们做大多数工作,但是如果我们像tooltip一样创建的新的dom节点,我们必须自定义方法来完成清理
       1 (function ($) {
       2   $.widget("ljq.tooltip", {
       3     _create: function ()
       4     {
       5       this._tooltipDiv = $("<div></div>")
       6         .addClass("ljq-tooltip-text ui-widget "
       7           + "ui-state-highlight ui-corner-all")
       8         .hide().appendTo("body");
       9       this.element.addClass("ljq-tooltip-trigger")
      10         .on("mouseenter.ljq-tooltip", $.proxy(this._open, this))
      11         .on("mouseleave.ljq-tooltip", $.proxy(this._close, this));
      12     }, // end _create()
      13     destroy: function ()
      14     {
      15       this._tooltipDiv.remove();
      16       this.element.removeClass("ljq-tooltip-trigger")
      17         .off(".ljq-tooltip");
      18       $.Widget.prototype.destroy.apply(this, arguments);
      19     }, // end destroy()
      20     _open: function ()
      21     {
      22       var elementOffset = this.element.offset();
      23       this._tooltipDiv.css({
      24         position: "absolute",
      25         left: elementOffset.left,
      26         top: elementOffset.top + this.element.height()
      27       }).text(this.element.data("tooltip-text"));
      28       this._tooltipDiv.show();
      29     }, // end _open()
      30     _close: function ()
      31     {
      32       this._tooltipDiv.hide();
      33     } // end _close()
      34   }); // end widget.toolip()
      35 }(jQuery));
    7. 使用和禁用控件:控件内建了enable和disable方法,这样就可以设置this.options.disabled在true和false之间切换,我们只需要在方法之间检查这个值即可,例如在_open中检测
       1     _open: function ()
       2     {
       3       if (this.options.disabled)
       4       {
       5         return;
       6       } // end if
       7       var elementOffset = this.element.offset();
       8       this._tooltipDiv.css({
       9         position: "absolute",
      10         left: elementOffset.left,
      11         top: elementOffset.top + this.element.height()
      12       }).text(this.element.data("tooltip-text"));
      13       this._tooltipDiv.show();
      14     }, // end _open()

      调用.tooltip("disable"); tooltip("enable");可以达到控制this.options.disabled的目的

    8. 控件接受参数:为控件添加options属性并配置所需的默认参数,控件工厂会判断用户调用控件时传递的参数并覆盖默认参数:
       1 (function ($) {
       2   $.widget("ljq.tooltip", {
       3     options: {
       4       offsetX: 10,
       5       offsetY: 10,
       6       content: function () {
       7         return $(this).data("tooltip-text") + " default option";
       8       }
       9     },
      10     _create: function ()
      11     {
      12       this._tooltipDiv = $("<div></div>")
      13         .addClass("ljq-tooltip-text ui-widget "
      14           + "ui-state-highlight ui-corner-all")
      15         .hide().appendTo("body");
      16       this.element.addClass("ljq-tooltip-trigger")
      17         .on("mouseenter.ljq-tooltip", $.proxy(this._open, this))
      18         .on("mouseleave.ljq-tooltip", $.proxy(this._close, this));
      19     }, // end _create()
      20     destroy: function ()
      21     {
      22       this._tooltipDiv.remove();
      23       this.element.removeClass("ljq-tooltip-trigger")
      24         .off(".ljq-tooltip");
      25       $.Widget.prototype.destroy.apply(this, arguments);
      26     }, // end destroy()
      27     _open: function ()
      28     {
      29       if (this.options.disabled)
      30       {
      31         return;
      32       } // end if
      33       var elementOffset = this.element.offset();
      34       this._tooltipDiv.css({
      35         position: "absolute",
      36         left: elementOffset.left + this.options.offsetX,
      37         top: elementOffset.top + this.element.height() + this.options.offsetY
      38       }).text(this.options.content.call(this.element[0]));
      39       this._tooltipDiv.show();
      40     }, // end _open()
      41     _close: function ()
      42     {
      43       this._tooltipDiv.hide();
      44     } // end _close()
      45   }); // end widget.toolip()
      46 }(jQuery));

      调用控件时.tooltip({offsetX: 0, offsetY: 1});会自动覆盖默认参数

    9. 自定义子方法,系统提供了默认的如destroy子方法。我们可以提供自定义子方法供用户调用,控件工厂会保证我们的方法支持链式调用
      1     open: function ()
      2     {
      3       this._open();
      4     }, // end open()
      5     close: function ()
      6     {
      7       this._close();
      8     }, // end close()

      .tooltip("close");  tooltip("open");即可调用,自定义子方法可接受参数,通过控件调用子方法的字符串后传入参数如:

      close: function (msg)
      {
        console.log(msg);  
      }
      
      $("a").tooltip();
      $("a").tooltip("close", "this is argument");
    10. 触发控件事件:在控件函数中调用this._trigger("eventname");会在添加了该控件的元素上触发一个自定义事件,事件名带有控件名作为前缀如this._trigger("open");会在元素上触发tooltipopen,这样就可以在元素上添加监听器了
       1     _open: function ()
       2     {
       3       if (this.options.disabled)
       4       {
       5         return;
       6       } // end if
       7       var elementOffset = this.element.offset();
       8       this._tooltipDiv.css({
       9         position: "absolute",
      10         left: elementOffset.left + this.options.offsetX,
      11         top: elementOffset.top + this.element.height() + this.options.offsetY
      12       }).text(this.options.content.call(this.element[0]));
      13       this._tooltipDiv.show();
      14       this._trigger("open");
      15     }, // end _open()
      16     _close: function ()
      17     {
      18       this._tooltipDiv.hide();
      19       this._trigger("close");
      20     } // end _close()
    11. 了解了为jQuery和jQuery UI添加扩展的常见内容,可以总结如下:
      1. 通过使用立即调用函数表达式保证$在自定义模块内不会失效
      2. 无论扩展$全局函数或者jQuery对象方法,最多在$定义一个属性。多余的公共方法和属性应该添加到控件名字空间($.myPlugin.publicMethod或者$.fn.myPlugin.pluginProperty)
      3. 为控件提供一个默认选项设置:$.fn.myPlugin.defaults = { size: "large"};
      4. 允许控件用户覆盖默认设置:$.fn.myPlugin.defaults.size = "medium"; $("div").myPlugin({size: "small"})
      5. 扩展jQuery对象原型时,返回this提供链式调用: $("div").myPlugin().find("p").addClass("foo")
      6. 扩展jQuery原型时,内部需要调用this.each()确保内部调用
      7. 适当提供回调函数增加控件灵活性
      8. jQuery UI控件通过控件工厂定义并且执行操作时检查控件状态
      9. 为控件提供自动单元测试,如使用QUnit框架
      10. 使用版本控制工具,如Git,把代码放到GitHub允许其他人对代码贡献
      11. 给控件选择一个合适的license
      12. 给控件提供完善的文档
    12. 完整代码
        1 <!doctype html>
        2 <html lang="zh">
        3 <head>
        4     <meta charset="utf-8">
        5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
        6     <meta name="description" content="">
        7     <meta name="author" content="">
        8     
        9     <title>Template Index</title>
       10   <style>
       11   </style>
       12 
       13     
       14 </head>
       15 <body>
       16   <table id="inventory">
       17     <thead>
       18       <tr class="one">
       19         <th>Product</th>
       20         <th>Quantity</th>
       21         <th>Price</th>
       22       </tr>
       23     </thead>
       24     <tfoot>
       25       <tr class="two" id="sum">
       26         <td>Total</td>
       27         <td></td>
       28         <td></td>
       29       </tr>
       30       <tr id="average">
       31         <td>Average</td>
       32         <td></td>
       33         <td></td>
       34       </tr>
       35     </tfoot>
       36     <tbody>
       37       <tr>
       38         <td><a href="span.html" data-tooltip-text="Nutritious and delicious!">Spam</a></td>
       39         <td>4</td>
       40         <td>2.50</td>
       41       </tr>
       42       <tr>
       43         <td><a href="egg.html" data-tooltip-text="Fram fresh or scrambled!">Egg</a></td>
       44         <td>12</td>
       45         <td>4.32</td>
       46       </tr>
       47       <tr>
       48         <td><a href="gourmet-spam.html" data-tooltip-text="Chef Hermans's recipe">Gourmet Span</a></td>
       49         <td>14</td>
       50         <td>7.89</td>
       51       </tr>
       52     </tbody>
       53   </table>
       54 
       55     <script src="js/jquery.js"></script>
       56   <script src="js/jquery-ui-core.js"></script>
       57   <script>
       58   (function ($)
       59   {
       60     $.sum = function (array)
       61     {
       62       var total = 0;
       63       $.each(array,
       64         function (index, value)
       65         {
       66           value = $.trim(value);
       67           value = parseFloat(value) || 0;
       68           total += value;
       69         } // end function
       70       );
       71       return total;
       72     }; // end sum()
       73     
       74     $.average = function (array)
       75     {
       76       if ($.isArray(array))
       77       {
       78         return $.sum(array) / array.length;
       79       } // end if
       80       return "";
       81     }; // end average()
       82     
       83   }(jQuery));
       84   
       85 (function ($) {
       86   $.widget("ljq.tooltip", {
       87     options: {
       88       offsetX: 10,
       89       offsetY: 10,
       90       content: function () {
       91         return $(this).data("tooltip-text") + " default option";
       92       }
       93     },
       94     _create: function ()
       95     {
       96       this._tooltipDiv = $("<div></div>")
       97         .addClass("ljq-tooltip-text ui-widget "
       98           + "ui-state-highlight ui-corner-all")
       99         .hide().appendTo("body");
      100       this.element.addClass("ljq-tooltip-trigger")
      101         .on("mouseenter.ljq-tooltip", $.proxy(this._open, this))
      102         .on("mouseleave.ljq-tooltip", $.proxy(this._close, this));
      103     }, // end _create()
      104     destroy: function ()
      105     {
      106       this._tooltipDiv.remove();
      107       this.element.removeClass("ljq-tooltip-trigger")
      108         .off(".ljq-tooltip");
      109       $.Widget.prototype.destroy.apply(this, arguments);
      110     }, // end destroy()
      111     open: function ()
      112     {
      113       this._open();
      114     }, // end open()
      115     close: function ()
      116     {
      117       this._close();
      118     }, // end close()
      119     _open: function ()
      120     {
      121       if (this.options.disabled)
      122       {
      123         return;
      124       } // end if
      125       var elementOffset = this.element.offset();
      126       this._tooltipDiv.css({
      127         position: "absolute",
      128         left: elementOffset.left + this.options.offsetX,
      129         top: elementOffset.top + this.element.height() + this.options.offsetY
      130       }).text(this.options.content.call(this.element[0]));
      131       this._tooltipDiv.show();
      132       this._trigger("open");
      133     }, // end _open()
      134     _close: function ()
      135     {
      136       this._tooltipDiv.hide();
      137       this._trigger("close");
      138     } // end _close()
      139   }); // end widget.toolip()
      140 }(jQuery));
      141   </script>
      142   <script>
      143   $(function (){
      144     var inventory = $("#inventory tbody");
      145     var quantities = inventory.find("td:nth-child(2)")
      146       .map(function (index, qty){
      147         return $(qty).text();
      148       }).get();
      149     var sum = $.sum(quantities);
      150     $("#sum").find("td:nth-child(2)").text(sum);
      151     
      152     var prices = inventory.find("td:nth-child(3)")
      153       .map(function (index, qty){
      154         return $(qty).text();
      155       }).get();
      156     var average = $.average(prices);
      157     $("#average").find("td:nth-child(3)").text(average.toFixed(2));
      158   
      159   var data = [3, 4, 3, 4, 3, 4, 3, 4];
      160 console.log("sum: " + $.sum(data));
      161 console.log("avreage: " + $.average(data));
      162 $("a").tooltip();
      163   
      164   });
      165   </script>
      166 </body>
      167 </html>
  • 相关阅读:
    iOS开发_当一个控件被添加到父控件中会调用
    iOS_判断应用在前台还是后台
    iOS开发_ SDWebImage先下载图片保存起来,需要时再调用
    WARNING ITMS90901: "Missing fullscreen support for the latest iPad mini display.
    iOS开发_显示带HTML标签的富文本
    iOS开发_WKWebView隐藏滚动条
    iOS_获取应用当前定位授权状态
    iOS开发_判断字符串是否为空的处理
    UIAlertController和UIActivityViewController在ipad中的兼容性问题
    npm run serve报错提示js堆内存不足
  • 原文地址:https://www.cnblogs.com/qiudeqing/p/3422101.html
Copyright © 2011-2022 走看看