jQuery自定义插件之tab标签切换

更多jQuery常用插件使用请访问:jQuery常用插件汇总


tab标签切换是网页中最常见不过的插件了,所以写一个自用的tab标签切换插件,偷懒一下。
上源码,想用的直接复制走,保存在一个js文件即可使用。

插件源码

/*
 * @Author: JiaoShou 
 * @Date: 2020-07-09 16:46:28 
 * @Last Modified by: JiaoShou
 * @Last Modified time: 2020-07-10 18:40:56
 */
;(function(window,$,undefined){

  $.fn.extend({
    /**
     * tab标签切换插件
     * 插件默认获取的是tan的父级,在父级下面去获取tab、content,所以写选择器的时候不需要单独写父级选择器了
     * @param {object} option  可选参数
     */
    'tab': function(option){
      var defaults = {
            index: 0,  //tabs焦点的索引值,如果用户传入的值不能转换成数值,将使用此默认值
            tab: '.tab-tab', //tba切换时候对应tab选择器(用于jq获取content元素集合,需要带#、.前缀),会在父级范围内获取,所以不需要带父级了
            class: 'tab-active', //tabs焦点的className
            attr: 'data-tab-index', //tabs需要增加的自定义属性,方便取焦点索引值使用的,防止data-index与其它自定义属性冲突
            autoplay: false,  //tabs是否自动切换
            speed: 1000,  //tabs自动切换速度,如果用户传入的值不能转换成数值,将使用此默认值
            eventType: '',  //触发焦点切换的事件类型,目前可传'click'、'touchend'。
            content: '',  //tbas切换时候对应需要切换的内容选择器(用于jq获取content元素集合,需要带#、.前缀),会在父级范围内获取,所以不需要带父级了,不需要内容切换的时候,此选项可不传值
            contentClass: 'tab-content-active', //content焦点的className
            contentAttr: 'data-tab-content-index', //content需要增加的自定义属性,方便取焦点索引值使用的,防止data-index与其它自定义属性冲突
            callbackContent: function(){},  //鼠标移入content时候的回调函数,比如仅在鼠标移入content之后,才会显示当前选中项
            callback: function(){}  //鼠标移入tabs时候的回调函数,比如仅在鼠标移入tabs之后,才会显示当前选中项
          },
          opts = $.extend({}, defaults, option);

      // 遍历插件对象,防止多个效果同步bug
      return this.each(function () {
        var tab = {
          $el: $(this),
          defaults: defaults,      //插件默认值
          iTabLength: 0,  //tabs的总个数
          index: opts.index,  //tabs焦点的索引值
          tab: opts.tab, //tbas切换时候对应tab选择器(用于jq获取content元素集合,需要带#、.前缀)
          class: opts.class,  //tabs焦点的className
          attr: opts.attr,  //tabs需要增加的自定义属性,方便取焦点索引值使用的
          autoplay: opts.autoplay,  //tabs是否自动切换
          speed: opts.speed,  //tabs自动切换速度
          eventType: opts.eventType,  //触发切换的事件类型
          content: opts.content,  //tbas切换时候对应需要切换的内容选择器(用于jq获取content元素集合),不需要内容切换的时候,此选项可不传值
          contentClass: opts.contentClass,  //content焦点的className
          contentAttr: opts.contentAttr,  //content需要增加的自定义属性,方便取焦点索引值使用的
          callbackContent: opts.callbackContent,  //鼠标移入content时候的回调函数
          callback: opts.callback,  //鼠标移入tabs时候的回调函数
          $tab: null,   //用jq获取tab元素集合
          $content: null,  //用jq获取content元素集合
          iContentLength: 0,  //用jq获取content元素集合
          timer: null,  //tabs定时器变量
          // 初始化函数
          'init': function(){
            // 规范初始化参数
            this.initProp();

            // 给tabs设置自定义属性
            this.setAttr();

            // 给content内容设置自定义属性
            this.setContentAttr();

            // 重新计算index,防止传入错误的范围
            this.countIndex();

            // 初始化焦点元素
            this.setFocus();

            // 自动切换事件,内部会自己判断
            this.play();

            // 鼠标移入tabs的事件
            this.enterTabs();

            // 鼠标移出tabs的事件
            this.leaveTabs();

            // 如果有切换内容,才给内容添加响应事件
            if (this.iContentLength>0) {
              // 鼠标移入content的事件
              this.enterContent();
    
              // 鼠标移出content的事件
              this.leaveContent();
            }
          },
          // 规范初始化参数
          'initProp': function(){
            if ($.trim(this.content).length > 0) {
              // 如果选择器不为空,说明有切换内容
              this.content = $.trim(this.content);
              this.$content = $(opts.content,this.$el);
              this.iContentLength = this.$content.length;
            }
            // 获取tab按钮
            this.$tab = $(opts.tab,this.$el);
            // 获取tabs的总长度
            this.iTabLength = this.$tab.length;
            // 规范规数值参数,防止手残输入错误,输入错误则恢复成插件默认值
            this.index = Number(this.index) || this.defaults.index;
            this.speed = Number(this.speed) || this.defaults.speed;

            // 规范字符串参数,去除首尾空格
            this.class = $.trim(this.class);
            this.attr = $.trim(this.attr);
            this.contentClass = $.trim(this.contentClass);
            this.contentAttr = $.trim(this.contentAttr);
          },
          // 切换tabs焦点样式
          'setFocus': function(){
            // 先清除样式,因为有可能不是同级,所以没用.siblings()方法清除样式
            this.$tab.removeClass(this.class);
            // 再给焦点添加样式
            this.$tab.eq(this.index).addClass(this.class);
            
            // 鼠标移入tabs时候的回调函数
            this.callback&&this.callback();

            // 如果有内容需要切换,就进行内容切换
            if (!!this.iContentLength) {
              this.setContentFocus();
            }
          },
          // 设置content焦点样式
          'setContentFocus': function(){
            // 先清除样式,因为有可能不是同级,所以没用.siblings()方法清除样式
            this.$content.removeClass(this.contentClass);
            // 再给焦点添加样式
            this.$content.eq(this.index).addClass(this.contentClass);
          },
          // 给tabs设置自定义属性,方便取索引值
          'setAttr': function(){
            // 存this对象,方便下面指向调用
            var _this = this;
            // 给每个tabs对象添加data-index自定义属性,方便取当前元素的索引值
            this.$tab.each(function(index) {
              // 切记!!!each回调里面的this是元素的js对象,没用jq方法
              this.setAttribute(_this.attr, index);
            });
          },
          // 给tabs设置自定义属性,方便取索引值
          'setContentAttr': function(){
            // 存this对象,方便下面指向调用
            var _this = this;
            // 如果有content内容需要切换,同样设置自定义属性
            if (!!this.iContentLength) {
              this.$content.each(function(index) {
                // 切记!!!each回调里面的this是元素的js对象,没用jq方法
                this.setAttribute(_this.contentAttr, index);
              });
            }
          },
          // 鼠标移入tabs的事件
          'enterTabs': function(){
            // 存this对象,方便下面指向调用
            var _this = this;
            // 移入元素清空定时器,并给当前元素设置焦点样式
            this.$tab.on('mouseenter',function(){
              // 清空定时器
              clearInterval(_this.timer);
              //  如果鼠标反复移入当前焦点,就不进行切换渲染
              if (_this.index == parseInt($(this).attr(_this.attr))) {
                return false;
              }
              if (_this.eventType == 'click') {
                $(this).on(_this.eventType,function(){
                  //  如果是当前焦点,就不进行切换渲染
                  if (_this.index != parseInt($(this).attr(_this.attr))) {
                    // 改变index索引值
                    _this.index=parseInt($(this).attr(_this.attr));
                    // 设置tabs焦点样式
                    _this.setFocus();
                  }
                  })
              }else{
                // 改变index索引值
                _this.index=parseInt($(this).attr(_this.attr));
                // 设置tabs焦点样式
                _this.setFocus();
              }
            });
          },
          // 鼠标移出tabs的事件
          'leaveTabs': function(){
            // 存this对象,方便下面指向调用
            var _this = this;
            // 移出元素开启定时器
            this.$tab.on('mouseleave',function(){
              _this.play();
            });
          },
          // 鼠标移入content的事件
          'enterContent': function(){
            // 存this对象,方便下面指向调用
            var _this = this;
            // 移入元素清空定时器,并给当前元素设置焦点样式
            this.$content.on('mouseenter',function(){
              // 清空定时器
              clearInterval(_this.timer);
              
              // 鼠标移入content时候的回调函数
              _this.callbackContent&&_this.callbackContent();
            });
          },
          // 鼠标移出content的事件
          'leaveContent': function(){
            // 存this对象,方便下面指向调用
            var _this = this;
            // 移出元素开启定时器
            this.$content.on('mouseleave',function(){
              _this.play();
            });
          },
          // 计算索引值是否超出tabs的最大长度
          'countIndex': function(){
            this.index = parseInt(this.index);
            // 如果index小于0,重置为0
            if (this.index<0) {
              this.index=0;
            }
            // 如果index超出tabs的总个数,index归零
            this.index = this.index % this.iTabLength;
          },
          // 焦点index自增事件
          'addIndex': function(_this){
            // 因为在定时器调用addIndex函数,this指向出现问题,所以需要修改this指向
            return function(){
              
              // index自增
              _this.index++;
              
              // 重新判断index 
              _this.countIndex();

              // 设置样式
              _this.setFocus(_this.index);
            }
          },
          // 自动焦点切换事件
          'play': function(){
            if (this.autoplay) {
              
              // 自动切换定时器
              this.timer = setInterval(this.addIndex(this), this.speed);
            }
          }
        };

        // 初始化tab函数
        tab.init();
        
      });
    }
  });
})(window,jQuery);


案例html布局

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>较瘦 - 博客园</title>
<style>
  *{
    margin: 0;
    padding: 0;
  }
  span{display: inline-block;}
  span.tab-active{background: rgb(38, 184, 221);}
  .tab div{ 100px;height: 100px;border: 1px solid #000;display: none;}
  .tab div.tab-content-active{background: rgb(38, 184, 221);display: block;}
  .tab div.active{background: rgb(245, 76, 9);display: block;}
</style>
<script src="./scripts/jQuery/jquery-1.8.3.min.js"></script>
<script src="./scripts/myjQuery/jquery.tab.js"></script>
</head>
<body>
<div class="tab tab1">
  <p>当前焦点是:<i></i></p>
<br/>
<br/>
<span>选项卡11</span>
<br/>
<span>选项卡22</span>
<br/>
<span>选项卡33</span>
<br/>
<span>选项卡44</span>
<br/>
<span>选项卡55</span>
<br/>
<div>内容111</div>
<br/>
<div>内容222</div>
<br/>
<div>内容333</div>
<br/>
<div>内容444</div>
<br/>
<div>内容555</div>
<br/>
</div>
<div class="tab tab2">
  <p>当前焦点是:<i></i></p>
<br/>
<br/>
<span>选项卡11</span>
<br/>
<span>选项卡22</span>
<br/>
<span>选项卡33</span>
<br/>
<span>选项卡44</span>
<br/>
<span>选项卡55</span>
<br/>
<div class="tab-content">内容111</div>
<br/>
<div class="tab-content">内容222</div>
<br/>
<div class="tab-content">内容333</div>
<br/>
<div class="tab-content">内容444</div>
<br/>
<div class="tab-content">内容555</div>
<br/>
</div>
<script>
$(function(){
    // $('.tab1').tab({'autoplay':true,'tab':'span','content':' div','speed':300});
    // $('.tab2').tab({'autoplay':true,'tab':'span'});
    $('.tab1').tab({
      autoplay:true,
      tab:'span',
      content: 'div',  //tbas切换时候对应需要切换的内容选择器(用于jq获取content元素集合),不需要内容切换的时候,此选项可不传值
      contentClass: 'active', //content焦点的className
      callback: function(){
        var str = this.$tab.eq(this.index).html() +'---'+ this.$content.eq(this.index).html();
        $('p i').html(str);
      }
    });
});
</script>
</body>
</html>

自定义tab标签切换插件使用方法

在页面中引入jquery和jquery.tab.js文件(根据项目目录引入必要文件)。

<script src="./js/jquery-1.11.3.min.js"></script>
<script src="./js/jquery.tab.js"></script>

HTML结构

没有特殊说明,只要可以选取到元素即可

初始化插件

在页面DOM元素加载完毕之后,通过tab()方法来初始化该插件。

$(function(){
    $('span').tab();
});

插件配置参数

该插件的可用配置参数有:

  • index :tabs焦点的索引值,也可以用于插件初始化的选中项用,如果用户传入的值不能转换成数值,将使用此默认值。默认为 0
  • tab :tba切换时候对应tab选择器(用于jq获取content元素集合,需要带#、.前缀),会在父级范围内获取,所以不需要带父级了。默认为 '.tab-tab'
  • class :tabs焦点的className。默认为 'tab-active'
  • attr :tabs需要增加的自定义属性,方便取焦点索引值使用的,防止data-index与其它自定义属性冲突。默认为 'data-tab-index
  • autoplay :tabs是否自动切换,默认不自动切换。默认为 false
  • speed :tabs自动切换速度,如果用户传入的值不能转换成数值,将使用此默认值。默认为 1000
  • eventType :触发焦点切换的事件类型,目前可传'click''touchend'。默认为 ''
  • content :tbas切换时候对应需要切换的内容选择器(用于jq获取content元素集合,需要带#、.前缀),会在父级范围内获取,所以不需要带父级了,不需要内容切换的时候,此选项可不传值。默认为 ``
  • contentClass :content焦点的className。默认为 'tab-content-active'
  • contentAttr :content需要增加的自定义属性,方便取焦点索引值使用的,防止data-index与其它自定义属性冲突。默认为 data-tab-content-index
  • callbackContent :鼠标移入content时候的回调函数,比如仅在鼠标移入content之后,才会显示当前选中项。默认为 function(){}
  • callback :鼠标移入tabs时候的回调函数,比如仅在鼠标移入tabs之后,才会显示当前选中项。默认为 function(){}

插件使用案例

使用一:最基础版 只需要切换三个span标签,这个插件所有的option都是可选项,都是可选项!!!

$(function () {
    $('.tab').tab({
      tab:'span', //tab选择器
    });
});

最基础的是不会自动切换的,需要鼠标移入才会切换,这个插件所有的option都是可选项,都是可选项!!!

使用二:设置默认值焦点,设置焦点className,自动切换,设置切换speed

$(function () {
    $('.tab').tab({
      tab:'span', //tab选择器
      index: 0,  //tabs焦点的索引值
      class: 'active', //tabs焦点的className
      attr: 'data-index', //tabs需要增加的自定义属性,方便取焦点索引值使用的,防止data-index与其它自定义属性冲突
      autoplay: false,  //tabs是否自动切换
      speed: 1000  //tabs自动切换速度
    });
});

使用三:设置内容同步切换,设置内容焦点className,设置tab切换时候,在p标签内显示当前焦点内容

$(function () {
    $('.tab1').tab({
      autoplay:true,
      tab:'span',
      content: 'div',  //tbas切换时候对应需要切换的内容选择器(用于jq获取content元素集合),不需要内容切换的时候,此选项可不传值
      contentClass: 'active', //content焦点的className
      callback: function(){
        var str = this.$tab.eq(this.index).html() +'---'+ this.$content.eq(this.index).html();
        $('p i').html(str);
      }
    });
});

好了,暂时就写这三个使用案例,仔细看一下代码,都有注释不是很难。

原文地址:https://www.cnblogs.com/jiaoshou/p/13205304.html