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 {
        width: 400px;
        margin: 50px auto;
        border: 1px solid #e5e5e5;
    }
    
    .tab-hd {
        height: 45px;
    }
    
    .tab-hd li {
        padding: 15px 0;
        width: 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 {
        width: 400px;
        margin: 50px auto;
        border: 1px solid #e5e5e5;
    }
    
    .tab-hd {
        height: 45px;
    }
    
    .tab-hd li {
        padding: 15px 0;
        width: 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 {
        width: 400px;
        margin: 50px auto;
        border: 1px solid #e5e5e5;
    }
    
    .tab-hd {
        height: 45px;
    }
    
    .tab-hd li {
        padding: 15px 0;
        width: 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 {
        width: 400px;
        margin: 50px auto;
        border: 1px solid #e5e5e5;
    }
    
    .tab-hd {
        height: 45px;
    }
    
    .tab-hd li {
        padding: 15px 0;
        width: 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的框架的細微的變形,萬變不離其中,只要了解基本的方法,其他的都可以依葫蘆畫瓢!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM