• jQuery插件


    jQuery插件的点点滴滴

    说起jQuery插件,很多人的脑海种已经有了一定的雏形,仿佛感觉仅仅就是那样子,事实呢?当你看了Bootstrap.js,品读了slidesjs,观摩了jquery.cycle2.js,不禁发现,原来插件的世界千变万化,细微之处总是不容易让人发觉,世界那么大,那么我们就一起去看看它到底长什么样子?

      工欲善其事必先利其器,如果你对于jQuery插件运用熟练的话,那么对已$.extend,你一定要去了解!,下面我们就先对$.extend来个剖析!先看看你对于$.extend的几种形式!

      一、$.extend的用法

    复制代码
    1 $.extend(dest,src1,src2,src3...)
    2 $.extend({},src1,src2,src3...)    
    3 $.extend({name:function(){}})    
    4 $.fn.extend({name:function(){}})    
    5 $.extend({net:{}})    
    6 $.extend({boolean,dest,src1,src2,src3...})
    复制代码

      

      $.extend(dest,src1,src2,src3...) 

      将src1,src2,src3...合并到dest中,请记住合并时,后面同名的属性会覆盖掉前面的属性,对于前面没有的属性,难就进行合并,如下: 

    复制代码
    <script type="text/javascript">
        $(function() {
            var obj = {
                    name: "yyh",
                    age: 26
                },
                obj1 = {
                    name: "yyh1",
                    age: 27
                },
                obj2 = {
                    name: "yyh2",
                    age: 27,
                    address:"chitu"
                }
            var mergeObj = $.extend(obj,obj1,obj2);
            console.log(mergeObj)//{name: "yyh2", age: 27, address: "chitu"}
        })
    </script>
    复制代码

      $.extend({},src1,src2,src3...) 

      这个和上面的是一样的,不同只是把dest={},把src1,src2,src3合并到一个空对象中,原理同上,不在赘述!

      

      $.extend({name:function(){}}) 

      看到这个东西,你可以这么认为,这是相当于$.extend(dest,src1) 中省略了dest后变成了$.extend(src1),这样子就相当于将该src合并到调用extend方法的对象中去,也就是将src合并到jquery的全局对象中去!举个例子,我们给jquery全局对象拓展一个是否支持CSS3的方法supportCSS3:

    复制代码
     1 <script type="text/javascript">
     2     $(function() {
     3         $.extend({
     4             supportCSS3: function() {
     5                 var body, i, style, transition, vendor;
     6                 body = document.body || document.documentElement;
     7                 style = body.style;
     8                 transition = "transition";
     9                 vendor = ["Moz", "Webkit", "Khtml", "O", "ms"];
    10                 transition = transition.charAt(0).toUpperCase() + transition.substr(1);
    11                 i = 0;
    12                 while (i < vendor.length) {
    13                     if (typeof style[vendor[i] + transition] === "string") {
    14                         return vendor[i];
    15                     }
    16                     i++;
    17                 }
    18                 return false;
    19             }
    20         })
    21         if($.supportCSS3){
    22             alert("该浏览器支持css33");
    23         }
    24     })
    25     </script>
    复制代码

       所以像$.get,$post,$.ajax就是jquery全局对象的方法!

       

      $.fn.extend({name:function(){}})

      和上面的$.extend相比,如果对于js的原型对象有了解,你肯定可以知道$.fn=jQuery.prototype,也就是说这种方式是把方法拓展到jquery对象的实例中,同样来个例子:

    复制代码
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>demo1</title>
     6     <script src="http://libs.baidu.com/jquery/1.10.0/jquery.js"></script>
     7 </head>
     8 <body>
     9     <button id="btn1">点击</button>
    10     <script type="text/javascript">
    11     $(function() {
    12         $.fn.extend({
    13             say: function() {
    14                 alert("我是丑男孩");
    15                 return this;//为什么加this,jquery的链式写法,你懂的!
    16             }
    17         });
    18         $("#btn1").on("click",function(){
    19             $(this).say().hide();
    20         })
    21 
    22     })
    23     </script>
    24 </body>
    25 </html>
    复制代码

      

      $.extend({net:{}})

      顾名思义,这个事在全局对象中扩展一个net命名空间,理解方式可以$.extend({name:function(){}}) 相似的。作用是干嘛?很简单假设团队有多个人,你担心推展到全局对象中会产生冲突,那么就自己独立建一个属于自己的空间,这样妈妈就在也不用担心儿子程序和别人冲突了!来个例子(如何来读取拓展的属性):

    复制代码
     1 <script type="text/javascript">
     2     $(function() {
     3         $.extend({
     4             yyh: {
     5                 age: 26,
     6                 address: "chitu",
     7                 supportCSS3: function() {
     8                     var body, i, style, transition, vendor;
     9                     body = document.body || document.documentElement;
    10                     style = body.style;
    11                     transition = "transition";
    12                     vendor = ["Moz", "Webkit", "Khtml", "O", "ms"];
    13                     transition = transition.charAt(0).toUpperCase() + transition.substr(1);
    14                     i = 0;
    15                     while (i < vendor.length) {
    16                         if (typeof style[vendor[i] + transition] === "string") {
    17                             return vendor[i];
    18                         }
    19                         i++;
    20                     }
    21                     return false;
    22                 }
    23 
    24             }
    25         });
    26         //读取对应的属性
    27         if($.yyh.supportCSS3){
    28             alert("浏览器支持css3");
    29         }
    30         console.log($.yyh.age);
    31         console.log($.yyh.address);
    32     })
    33     </script>
    复制代码

      $.extend(boolean,dest,src1,src2,src3...)

      这中方式,通过boolean,来决定是否深度拷贝!这种方式想必你在很多场合也见过了,boolean默认的是false,可以省略!至于为什么这样做呢?来个例子就豁然开朗了!

    复制代码
     1 <script type="text/javascript">
     2     $(function() {
     3         var obj = {
     4                 name:{
     5                     nickname:"丑男孩",//外号
     6                     truename:"yyh",//真是姓名
     7                 },
     8                 age: 26
     9             },
    10             obj1 = {
    11                 name:{
    12                     nickname:"小男孩",//外号
    13                     truename:"yyh1",//真是姓名
    14                 },
    15                 age:25
    16             },
    17             obj2 = {
    18                 name:{
    19                     nickname:"老男孩",//外号
    20                     username:"uglyboy"
    21                 },
    22                 age: 27
    23             }
    24         var mergeObj1 = $.extend(true,obj,obj1,obj2);
    25         //mergeObj1={name:{nickname: "老男孩",truename: "yyh1",username: "uglyboy",age: 27}}
    26         var mergeObj2 = $.extend(false,obj,obj1,obj2);
    27         //mergeObj2={name:{nickname: "老男孩",username: "uglyboy",age: 27}}
    28     })
    29     </script>
    复制代码

      

      看完上面的例子的时候,你就知道如果false的时候,后面添加的对象的obj2中没有属性truename,合并后对象就不会有truename这个属性,所以写插件的时候会在里面看到如下:

    复制代码
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>demo1</title>
     6     <script src="http://libs.baidu.com/jquery/1.10.0/jquery.js"></script>
     7 </head>
     8 
     9 <body>
    10     <script type="text/javascript">
    11     ;(function($){
    12         $.fn.Plugin=function(options){
    13             //如果defaults是下面的形式,这里大可以不加boolean
    14             var defaults={
    15                 property1:"value1",
    16                 property2:"value2",
    17                 property3:"value3",
    18                 method1:function(){},
    19                 method2:function(){},
    20             };
    21             var opt=$.extend(defaults,options);
    22         }
    23     })(jQuery)
    24 
    25     ;(function($){
    26         $.fn.Plugin=function(options){
    27             //如果defaults是下面的形式,亲,记得加上boolean,不然传递参数可麻烦了!
    28             var defaults={
    29                 property1:{
    30                     property11:"value11",
    31                     property12:"value12",
    32                 },
    33                 property2:{
    34                     property21:"value21",
    35                     property22:"value22",
    36                 },
    37                 property3:{
    38                     property31:"value31",
    39                     property32:"value32",
    40                 },
    41                 method1:function(){},
    42                 method2:function(){},
    43             };
    44             
    45             var opt=$.extend(true,defaults,options);
    46         }
    47     })(jQuery)
    48 
    49     </script>
    50 </body>
    51 
    52 </html>
    复制代码

      二、jquery插件的几种形式

      1、传统的插件写法,defaut没有暴露出来供外部调用(这个应该我们写插件很常用的一种方式),下面是单个实例的时候

    复制代码
    <!doctype html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>无标题文档</title>
        <script src="http://libs.baidu.com/jquery/1.10.1/jquery.js"></script>
        <link rel="stylesheet" type="text/css" href="../css/reset.css">
        <style type="text/css">
        .undis {
            display: none;
        }
        
        .tab-parent {
             400px;
            margin: 50px auto;
            border: 1px solid #e5e5e5;
        }
        
        .tab-hd {
            height: 45px;
        }
        
        .tab-hd li {
            padding: 15px 0;
             200px;
            text-align: center;
            float: left;
            border-bottom: 1px solid #e5e5e5;
        }
        
        .tab-hd li.oncurr {
            border-color: #f60;
            color: #f60;
            font-weight: bold;
        }
        
        .tab-bd {
            padding: 20px;
            min-height: 250px;
        }
        </style>
    </head>
    
    <body>
        <div class="tab-parent" id="J_tab-parent">
            <ul class="tab-hd">
                <li class="tab-hd-item oncurr">选项卡1</li>
                <li class="tab-hd-item">选项卡2</li>
            </ul>
            <div class="tab-bd">
                <div class="tab-bd-item">选项卡1对应的内容</div>
                <div class="tab-bd-item undis">选项卡2对应的内容</div>
            </div>
        </div>
        <script type="text/javascript">
        (function($) {
            $.fn.Tab = function(options) {
                var defaults = {
                    hdClass: '.tab-hd-item',
                    bdClass: '.tab-bd-item'
                };
                var opts = $.extend(defaults, options),
                    $hdItems=this.find(opts.hdClass),
                    $bdItems=this.find(opts.bdClass);
                $hdItems.each(function(index, el) {
                    var $this=$(this);
                    $this.on("click",function(){
                        $this.addClass('oncurr').siblings().removeClass('oncurr');
                        $bdItems.eq(index).show().siblings().hide();
                    })
                }); 
          //如果想要支持链式写法,在这里请添加return this;  } })(jQuery); $(function() { $("#J_tab-parent").Tab(); }) </script> </body> </html>
    复制代码

      多个实例的时候

    复制代码
    <!doctype html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>无标题文档</title>
        <script src="http://libs.baidu.com/jquery/1.10.1/jquery.js"></script>
        <link rel="stylesheet" type="text/css" href="../css/reset.css">
        <style type="text/css">
        .undis {
            display: none;
        }
        
        .tab-parent {
             400px;
            margin: 50px auto;
            border: 1px solid #e5e5e5;
        }
        
        .tab-hd {
            height: 45px;
        }
        
        .tab-hd li {
            padding: 15px 0;
             200px;
            text-align: center;
            float: left;
            border-bottom: 1px solid #e5e5e5;
        }
        
        .tab-hd li.oncurr {
            border-color: #f60;
            color: #f60;
            font-weight: bold;
        }
        
        .tab-bd {
            padding: 20px;
            min-height: 250px;
        }
        </style>
    </head>
    
    <body>
        <div class="tab-parent" id="J_tab-parent">
            <ul class="tab-hd">
                <li class="tab-hd-item oncurr">选项卡1</li>
                <li class="tab-hd-item">选项卡2</li>
            </ul>
            <div class="tab-bd">
                <div class="tab-bd-item">选项卡1对应的内容</div>
                <div class="tab-bd-item undis">选项卡2对应的内容</div>
            </div>
        </div>
    
        <div class="tab-parent" id="J_tab-parent">
            <ul class="tab-hd">
                <li class="tab-hd-item oncurr">选项卡1</li>
                <li class="tab-hd-item">选项卡2</li>
            </ul>
            <div class="tab-bd">
                <div class="tab-bd-item">选项卡1对应的内容</div>
                <div class="tab-bd-item undis">选项卡2对应的内容</div>
            </div>
        </div>
        <script type="text/javascript">
        (function($) {
            $.fn.Tab = function(options) {
                var defaults = {
                    hdClass: '.tab-hd-item',
                    bdClass: '.tab-bd-item'
                };
                var opts = $.extend(defaults, options);
                return this.each(function(index, el) {
                    var $hdItems=$(this).find(opts.hdClass),
                        $bdItems=$(this).find(opts.bdClass);
                        $hdItems.each(function(index, el) {
                            var $this=$(this);
                            $this.on("click",function(){
                                $this.addClass('oncurr').siblings().removeClass('oncurr');
                                $bdItems.eq(index).show().siblings().hide();
                            })
                        });  
                });
                    
                
            }
        })(jQuery);
        $(function() {
            $(".tab-parent").Tab();
        })
        </script>
    </body>
    </html>
    复制代码

      

      2、default写成$.fn.default暴露出来供外部调用(这种方式的插件写法是很经常遇到的,比如jquery.cycle2.js),这个时候你应该会联想到$.fn.format在插件中的用法,这样的好处是可以让用户自定义自己的操作行为,而不用每次实例的时候都去传递同样的阐述,如下的例子:

    复制代码
    <!doctype html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>无标题文档</title>
        <script src="http://libs.baidu.com/jquery/1.10.1/jquery.js"></script>
        <link rel="stylesheet" type="text/css" href="../css/reset.css">
        <style type="text/css">
        .undis {
            display: none;
        }
        
        .tab-parent {
             400px;
            margin: 50px auto;
            border: 1px solid #e5e5e5;
        }
        
        .tab-hd {
            height: 45px;
        }
        
        .tab-hd li {
            padding: 15px 0;
             200px;
            text-align: center;
            float: left;
            border-bottom: 1px solid #e5e5e5;
        }
        
        .tab-hd li.oncurr {
            border-color: #f60;
            color: #f60;
            font-weight: bold;
        }
        
        .tab-bd {
            padding: 20px;
            min-height: 250px;
        }
        </style>
    </head>
    
    <body>
        <div class="tab-parent" id="J_tab-parent">
            <ul class="tab-hd">
                <li class="tab-hd-item-1 oncurr">选项卡1</li>
                <li class="tab-hd-item-1">选项卡2</li>
            </ul>
            <div class="tab-bd">
                <div class="tab-bd-item-1">选项卡1对应的内容</div>
                <div class="tab-bd-item-1 undis">选项卡2对应的内容</div>
            </div>
        </div>
        <script type="text/javascript">
        (function($) {
            $.fn.Tab = function(options) {
                var opts = $.extend($.fn.Tab.defaults, options);
                return this.each(function(index, el) {
                    var $hdItems = $(this).find(opts.hdClass),
                        $bdItems = $(this).find(opts.bdClass);
                    $hdItems.each(function(index, el) {
                        var $this = $(this);
                        $this.on("click", function() {
                            $(this).html($.fn.Tab.format($(this).text()));
                            $this.addClass('oncurr').siblings().removeClass('oncurr');
                            $bdItems.eq(index).show().siblings().hide();
                        })
                    });
                });
            }
            $.fn.Tab.defaults = {
                hdClass: '.tab-hd-item',
                bdClass: '.tab-bd-item'
            };
            $.fn.Tab.format = function(txt) {
                return '<strong>' + txt + '</strong>';
            };
        })(jQuery);
        $(function() {
            $.fn.Tab.defaults = {
                hdClass: '.tab-hd-item-1',
                bdClass: '.tab-bd-item-1'
            };
            $(".tab-parent").Tab();
        })
        </script>
    </body>
    
    </html>
    复制代码

      3、通过data的方式来实现jquery插件的写法(参考bootstrap.js,slidesjs)  

    复制代码
    <!doctype html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>无标题文档</title>
        <script src="http://libs.baidu.com/jquery/1.10.1/jquery.js"></script>
        <link rel="stylesheet" type="text/css" href="../css/reset.css">
        <style type="text/css">
        .undis {
            display: none;
        }
        
        .tab-parent {
             400px;
            margin: 50px auto;
            border: 1px solid #e5e5e5;
        }
        
        .tab-hd {
            height: 45px;
        }
        
        .tab-hd li {
            padding: 15px 0;
             200px;
            text-align: center;
            float: left;
            border-bottom: 1px solid #e5e5e5;
        }
        
        .tab-hd li.oncurr {
            border-color: #f60;
            color: #f60;
            font-weight: bold;
        }
        
        .tab-bd {
            padding: 20px;
            min-height: 250px;
        }
        </style>
    </head>
    
    <body>
        <div class="tab-parent" id="J_tab-parent">
            <ul class="tab-hd">
                <li class="tab-hd-item oncurr">选项卡1</li>
                <li class="tab-hd-item">选项卡2</li>
            </ul>
            <div class="tab-bd">
                <div class="tab-bd-item">选项卡1对应的内容</div>
                <div class="tab-bd-item undis">选项卡2对应的内容</div>
            </div>
        </div>
        <script type="text/javascript">
        ;(function($, window, document, undefined) {
            var pluginName = 'Tab',
                defaults = {
                    hdClass: '.tab-hd-item',
                    bdClass: '.tab-bd-item'
                };
    
            function Plugin(element, options) {
                this.element = element;
                this.options = $.extend({}, defaults, options);
                this._defaults = defaults;
                this._name = pluginName;
                this.init();
            }
            Plugin.prototype.init = function() {
                this.$hdItems = $(this.element).find(".tab-hd-item");
                this.$bdItems = $(this.element).find(this.options.bdClass);
                var _this = this;
                this.$hdItems.each(function(index, el) {
                    var $this = $(this);
                    $this.on("click", function() {
                        $this.addClass('oncurr').siblings().removeClass('oncurr');
                        _this.$bdItems.eq(index).show().siblings().hide();
                    })
                });
            }
            $.fn[pluginName] = function(options) {
                return this.each(function() {
                    if (!$.data(this, 'plugin_' + pluginName)) {
                        return $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
                    }
                })
            }
    
        })(jQuery, window, document);
    
        $(function() {
            $("#J_tab-parent").Tab()
        })
        </script>
    </body>
    
    </html>
    复制代码

       基本的插件形式就这这三种,当然我们依然可以找到其他的方式的插件,比如私有方法的放置,还有像bootstrap.js的框架的细微的变形,万变不离其中,只要了解基本的方法,其他的都可以依葫芦画瓢!

     
    分类: jQuery
    标签: js
  • 相关阅读:
    Mysql 存储引擎中InnoDB与Myisam的主要区别
    [转]memmove函数
    _Obj* __STL_VOLATILE* __my_free_list
    [转]STL的内存分配器
    [转载]C++ 堆与栈简单的介绍
    [转载]__type_traits
    [转载]C++中 引用&与取地址&的区别
    [转载]delete指针之后应该赋值NULL
    [转载]C++中声明与定义的区别
    学习笔记ubuntu/shell
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4582083.html
Copyright © 2020-2023  润新知