jquery的tab插件封裝

jquery插件的封裝過程。

jquery插件封裝

使用過不少的jquery的插件,可是不瞭解它們究竟是怎樣作的,今天就來封裝一個最多見的tab插件,看看具體的封裝過程。
tip:完整代碼下載在最後面,須要的直接跳過去看javascript

1.html結構

常見的tab支持自動切換,點擊切換,動畫切換,默認選擇等等,根據這些功能先來把html結構搭建起來:css

//index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>tab選項卡封裝插件</title>
</head>
<body>
<div class="tab js-tab">
        <ul class="tab_nav">
            <li class="active"><a href="javascript:;">新聞</a></li>
            <li><a href="javascript:;">娛樂</a></li>
            <li><a href="javascript:;">電影</a></li>
            <li><a href="javascript:;">科技</a></li>
        </ul>
        <div class="content_wrap">
            <div class="content_item current">a</div>
            <div class="content_item">b</div>
            <div class="content_item">c</div>
            <div class="content_item">d</div>
        </div>
    </div>
</body>
</html>

它是長這個樣子,夠醜,下一步來美化一下:
tabhtml

2.css樣式

引入個tab.css樣式,書寫一下樣式:java

//tab.css
*{margin: 0;padding: 0;}
ul,li{list-style: none;}
body{padding: 100px;background-color: #323232;font-size: 12px;font-family: "微軟雅黑";}
p{color:#6ec;font-weight: bold; background: #fff;height:20px;line-height: 20px;border-radius: 5px;padding:5px;}

.tab_view{
    float: left;
    margin-right: 50px;
}
.tab_view p{
    color: #999;
    margin: 20px 0;
}
.tab{
    width: 300px;
}
.tab_nav{
    height: 30px;
}
.tab_nav li{
    float: left;
    margin-right: 5px;
    background-color: #767676;
    border-radius: 3px 3px 0 0;
}
.tab_nav li a{
    display: block;
    height: 30px;
    line-height: 30px;
    padding: 0 20px;
    color: #fff;
    text-decoration: none;
}
.tab_nav li.active{
    background-color: #fff;
}
.tab_nav li.active a{
    color: #767676;
}

.content_wrap{
    height: 200px;
    padding: 5px;
    background-color: #fff;
}
.content_item{
    font-size: 60px;
    text-align: center;
    line-height: 200px;
    width: 290px;
    height: 200px;
    display: none;
    position: absolute;
}
.content_wrap div.current{
    display: block;
}
.content_item:first-child{
    background-color: gray;
}
.content_item:nth-child(2){
    background-color: lightblue;
}
.content_item:nth-child(3){
    background-color: pink;
}
.content_item:nth-child(4){
    background-color: lightgreen;
}

它就長成這個樣子了,看着舒服多了,立刻進行下一步,插件封裝:
tabjquery

3.js邏輯

3.1基本結構

在封裝插件前,先來引入jquery和tab.js,在tab.js中進行具體的開發:
1.在開發前想一下,須要怎麼來使用這個插件?確定是new Tab(選擇器),新建類後傳入選擇器,那若是想傳遞一些自定義的配置怎麼作呢?
能夠在html上加個data-config字段用於存放配置,而後使用getConfig()函數來得到segmentfault

//index.html
<div class="tab js-tab" data-config='{
                                            "triggerType":"click",
                                            "effect":"fade",
                                            "invoke":1,
                                            "auto":3000
                                        }'>
//其餘內容                                        
</div>
<script>
    $(function(){
        var tab = new Tab($(".js-tab").eq(0))
    });
</script>
//tab.js
;(function($){
    
    var Tab = function(tab){
        //這裏寫屬性
        
    };
    Tab.prototype = {
        //這裏寫方法
    }
    
    //把類掛載在全局
    window.Tab = Tab;
})(jQuery);

3.2配置參數

2.基礎的結構寫好了,接下來就是要處理配置,用戶可能會傳入參數也可能不會,因此默認參數是必需要提早來寫好的,而後得到用戶傳入的參數,對比一下,看哪些寫過哪些沒寫,把寫過的保存,沒寫的使用默認項
如何實現呢?
使用jQuery.extend(),它用於合併對象,若是隻爲$.extend()指定了一個參數,則之前的配置捨棄直接用新的。若是多個對象具備相同的屬性,則後者會覆蓋前者的屬性值
有了解決方法,能夠直接來寫了jquery插件

;(function($){
    
    var Tab = function(tab){
        //這裏寫屬性
          var _this = this;
        // 保存單個tab組件
        this.tab = tab;
        // 默認配置參數
        this.config = {
            "triggerType":"mouseover", // 用來定義鼠標的觸發類型,是click仍是mouseover
            "effect":"default", // 用來定義內容切換效果,是直接切換仍是淡入淡出效果
            "invoke":1, // 默認展現第幾個tab
            "auto":false // 定義tab是否自動切換,及自動切換時間間隔
        };
      // 若是配置參數存在,就擴展掉默認配置參數
        if(this.getConfig()){
            $.extend(this.config,this.getConfig());
        }
        
    };
    Tab.prototype = {
        //這裏寫方法
      // 獲取配置參數
        getConfig: function(){
            // 拿一下tab elem節點上的data-config
            var config = this.tab.attr("data-config");
            // 確保有配置參數
            if(config&&config!=""){
                return $.parseJSON(config);
            }else{
                return null;
            }
        }
    }
    
    //把類掛載在全局
    window.Tab = Tab;
})(jQuery);

測試一下,若是沒有傳參,會不會將默認配置寫上:
test
再測試一下,若是傳某幾項參數,會不會將配置混合:
xxsvg

3.3事件交互

接着來開發,接下來就能夠來添加一些事件交互效果了,有哪些效果呢?點擊和鼠標滑過,先來看點擊,要想點擊確定得先獲取到點擊的內容,就是在html寫的li標籤,this.tab.find("ul.tab_nav li")
同時當點擊了li標籤中的分類後,應該對應的顯示不一樣的內容,因此這部份內容也要獲取到,this.tab.find("div.content_wrap div.content_item")
而後判斷屬於點擊事件仍是鼠標滑過事件,爲它添加上對應的樣式和修改對應的內容,這個在invoke中實現,有了思路,直接來寫:函數

;(function($){
    
    var Tab = function(tab){
        //前面內容省略
      // 保存tab標籤列表、對應的內容列表
        this.tabItems = this.tab.find("ul.tab_nav li");
        this.contentItems = this.tab.find("div.content_wrap div.content_item");

        // 保存配置參數
        var config = this.config;

        if(config.triggerType === "click"){
            this.tabItems.bind(config.triggerType,function(){
                _this.invoke($(this));
            })
        }else if(config.triggerType != "click"){
            this.tabItems.bind("mouseover",function(){
                _this.invoke($(this));
            })
        }
        
      
        
    };
    Tab.prototype = {
        //這裏寫方法
      //前面的省略
      // 事件操做函數
        invoke: function(currentTab){
            var _this = this;
            var index = currentTab.index();
            // tab選中狀態
            currentTab.addClass('active').siblings().removeClass('active');
            // 切換對應的內容區域
            var effect = this.config.effect;
            var conItems = this.contentItems;
            if(effect === "default" || effect != "fade"){
                conItems.eq(index).addClass('current').siblings().removeClass('current');
            }else if(effect === "fade"){
                conItems.eq(index).fadeIn().siblings().fadeOut();
            };
            // 注意:若是參數配置了自動切換時間,要把當前的loop的值設置成當前tab的index
            if(this.config.auto){
                this.loop = index;
            }
        },
    }
    
    //把類掛載在全局
    window.Tab = Tab;
})(jQuery);

至此,應該能實現點擊或鼠標滑過修改樣式和更改內容,測試一下:
tsstoop

3.4自動切換

上面實現了手動的點擊或者鼠標滑過期切換的功能,但實際的tab插件是有自動切換的功能,如何來實現呢?可使用setInterval來實現,週期就是data-config中的auto,在回調函數中依次以點擊或者鼠標滑過的方式來觸發,如何實現依次調用?寫個循環的變量this.loop = 0;如何自動觸發呢?jquery有一個trigger方法,它就是用來自動觸發選中的事件的,思路有了,開寫:

;(function($){
    
    var Tab = function(tab){
        //前面內容省略
      // 自動切換功能,若是配置了時間,咱們就根據時間間隔進行自動切換
        if(config.auto){
            // 定義一個全局的定時器
            this.timer = null;
            // 計數器
            this.loop = 0;
            this.autoPlay();
        }
        
    };
    Tab.prototype = {
        //這裏寫方法
      //前面的省略
     // 自動間隔時間切換
        autoPlay: function(){
            var _this = this,
                tabItems = this.tabItems, // 臨時保存tab列表
                tabLength = tabItems.size(), // tab的個數
                config = this.config;
            this.timer = window.setInterval(function(){
                _this.loop ++;
                if(_this.loop >= tabLength){
                    _this.loop = 0;
                };
                tabItems.eq(_this.loop).trigger(config.triggerType);
            },config.auto);
        },
    }
    
    //把類掛載在全局
    window.Tab = Tab;
})(jQuery);

ok,測試一下,此時應該會自動的進行切換:

chaneg

確實實現了自動切換,可是當鼠標放在上面的時候,它停不住,這個須要來解決一下,添加個hover,而後在懸浮的時候清除一下setInterval

this.tab.hover(function(){
    window.clearInterval(_this.timer);
    },function(){
    _this.autoPlay();
    });

hover

ok,搞定,在鼠標放上去的時候他會自動中止,移開後又自動的循環

3.5默認選項

終於到了最後一個功能,須要傳入某個默認選擇時,從該選擇開始循環,這個有了前面的鋪墊就好實現了,只須要簡單設置一下就好了this.tabItems.eq(config.invoke-1)

;(function($){
    
    var Tab = function(tab){
        //前面內容省略
      // 設置默認顯示第幾個tab
        if(config.invoke > 1){
            this.invoke(this.tabItems.eq(config.invoke-1));
        }
        
    };
    Tab.prototype = {
        //這裏寫方法
      //前面的省略
    }
    
    //把類掛載在全局
    window.Tab = Tab;
})(jQuery);

測試一下,看看它會不會從第二個開始循環:

loop

ok,全部的功能都實現了,是時候考慮一下用戶使用的便捷性了,在上面使用這個插件的時候是經過 var tab = new Tab($(".js-tab").eq(0)) 這樣來實現的,可是實際的插件使用應該是 Tab.init($(".js-tab"));或者$(".js-tab").tab();這樣的來調用,就須要來把new的這個過程給封裝卡來,each方法把傳入的內容給都new一遍,或者$.fn.extend()直接把它加在jquery上,實現一下:

;(function($){
    
    var Tab = function(tab){
        //前面內容省略
    };
    Tab.prototype = {
      //前面的省略
    }
    Tab.init = function(tabs){
        var _this = this;
        tabs.each(function(){
            new _this($(this));
        })
    }
    // 註冊成jq方法
    $.fn.extend({
        tab: function(){
            this.each(function(){
                new Tab($(this));
            });
            return this;
        }
    })
    //把類掛載在全局
    window.Tab = Tab;
})(jQuery);

測試一下:
ree

ok,整個插件就作好了,作這個關鍵瞭解了封裝jquery插件的流程,之後就能夠本身來封裝屬於本身的jquery插件了。

這個過程,是學習自這個教程:https://www.imooc.com/learn/825,你們能夠去看看。
完整代碼下載:http://zuitingliu.com/?p=163

相關文章
相關標籤/搜索