jquery的tab插件封装

88570299 2019-11-19

jquery插件的封装过程。

jquery插件封装

使用过很多的jquery的插件,但是不了解它们到底是怎样做的,今天就来封装一个最常见的tab插件,看看具体的封装过程。
tip:完整代码下载在最后面,需要的直接跳过去看

1.html结构

常见的tab支持自动切换,点击切换,动画切换,默认选择等等,根据这些功能先来把html结构搭建起来:

//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>

它是长这个样子,够丑,下一步来美化一下:
jquery的tab插件封装

2.css样式

引入个tab.css样式,书写一下样式:

//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;
}

它就长成这个样子了,看着舒服多了,马上进行下一步,插件封装:
jquery的tab插件封装

3.js逻辑

3.1基本结构

在封装插件前,先来引入jquery和tab.js,在tab.js中进行具体的开发:
1.在开发前想一下,需要怎么来使用这个插件?肯定是new Tab(选择器),新建类后传入选择器,那如果想传递一些自定义的配置怎么做呢?
可以在html上加个data-config字段用于存放配置,然后使用getConfig()函数来获得

//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()指定了一个参数,则以前的配置舍弃直接用新的。如果多个对象具有相同的属性,则后者会覆盖前者的属性值
有了解决方法,可以直接来写了

;(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);

测试一下,如果没有传参,会不会将默认配置写上:
jquery的tab插件封装
再测试一下,如果传某几项参数,会不会将配置混合:
jquery的tab插件封装

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);

至此,应该能实现点击或鼠标滑过修改样式和更改内容,测试一下:
jquery的tab插件封装

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,测试一下,此时应该会自动的进行切换:

jquery的tab插件封装

确实实现了自动切换,但是当鼠标放在上面的时候,它停不住,这个需要来解决一下,添加个hover,然后在悬浮的时候清除一下setInterval

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

jquery的tab插件封装

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);

测试一下,看看它会不会从第二个开始循环:

jquery的tab插件封装

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);

测试一下:
jquery的tab插件封装

ok,整个插件就做好了,做这个关键了解了封装jquery插件的流程,以后就可以自己来封装属于自己的jquery插件了。

这个过程,是学习自这个教程:https://www.imooc.com/learn/825,大家可以去看看。
完整代码下载:http://zuitingliu.com/?p=163

相关推荐

Web全栈笔记 / 0评论 2020-06-15