美文网首页
Bootstrap插件解析3 切换标签

Bootstrap插件解析3 切换标签

作者: 波拉拉 | 来源:发表于2020-03-14 22:16 被阅读0次

1 如何使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap 101 Template</title>

    <link href="bootstrap.css" rel="stylesheet">
    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
</head>
<body>
<div class="container">
    <ul class="nav nav-tabs">
        <li class="active"><a href="#home" data-toggle="tab">Home</a></li>
        <li><a href="#profile" data-toggle="tab">Profile</a></li>
        <li><a href="#messages" data-toggle="tab">Messages</a></li>
        <li><a href="#settings" data-toggle="tab">Settings</a></li>
    </ul>
</div>

<div class="container">
    <div class="tab-content">
        <div role="tabpanel" class="tab-pane active" id="home">标签内容1</div>
        <div role="tabpanel" class="tab-pane" id="profile">标签内容2</div>
        <div role="tabpanel" class="tab-pane" id="messages">标签内容3</div>
        <div role="tabpanel" class="tab-pane" id="settings">标签内容4</div>
    </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="bootstrap.js"></script>
<script>
</script>
</body>
</html>

2 整体结构

(function ($) {
    // 构造函数
    var Tab = function (element) {};
    // 静态变量
    Tab.VERSION = '3.3.7';
    //原型方法
    Tab.prototype.show = function () {};
    Tab.prototype.activate = function(){};
    // 插件入口
    function Plugin(option) {}
    var old = $.fn.tab;
    //暴露插件 静态变量存储原构造函数
    $.fn.tab             = Plugin;
    $.fn.tab.Constructor = Tab;
    //防冲突处理
    $.fn.tab.noConflict = function (){};
    //data-api实现插件
    var clickHandler = function (e) {};//点击处理
    $(document)//绑定DOM
        .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
        .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
})(jQuery);

3 插件入口

  function Plugin(option) {
      //遍历jq对象处理
    return this.each(function () {
      var $this = $(this);
      //获取自定义数据,第一次;undefined
      var data  = $this.data('bs.tab');
      //如果没有,new构造函数保存到自定义数据中
      if (!data) $this.data('bs.tab', (data = new Tab(this)));
      //如果传入字符串,执行原型上的方法
      if (typeof option == 'string') data[option]()
    })
  }

  var old = $.fn.tab;
  //将插件暴露出来
  $.fn.tab             = Plugin;
  //指向原构造函数
  $.fn.tab.Constructor = Tab;
  //防冲突处理
  $.fn.tab.noConflict = function () {
    $.fn.tab = old;
    return this
  };

4 data-api插件实现

  //点击处理函数
  var clickHandler = function (e) {
    //取消默认行为
    e.preventDefault();
    //执行插件原型的show方法
    Plugin.call($(this), 'show')
  };
  //data上绑定方法,实现功能
  $(document)
    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)

5 构造函数+静态变量

  var Tab = function (element) {
    this.element = $(element)
  };

  Tab.VERSION = '3.3.7';//插件版本

  Tab.TRANSITION_DURATION = 150;//动画持续时间

6 原型方法

Tab.prototype.show = function () {
    var $this    = this.element;//点击切换的按钮
    var $ul      = $this.closest('ul:not(.dropdown-menu)');//包含的容器
    var selector = $this.data('target');// data-target="#home"
    // 没有data-target的处理
    if (!selector) {
      selector = $this.attr('href');
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '');
    }
    //li上有active,返回
    if ($this.parent('li').hasClass('active')) return;

    var $previous = $ul.find('.active:last a');
    var hideEvent = $.Event('hide.bs.tab', {
      relatedTarget: $this[0]
    });//自定义隐藏事件
    var showEvent = $.Event('show.bs.tab', {
      relatedTarget: $previous[0]
    });//自定义显示事件

    $previous.trigger(hideEvent);
    $this.trigger(showEvent);

    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return;

    var $target = $(selector);//对应的内容
    //执行激活方法
    this.activate($this.closest('li'), $ul)
    this.activate($target, $target.parent(), function () {
      $previous.trigger({
        type: 'hidden.bs.tab',
        relatedTarget: $this[0]
      });
      $this.trigger({
        type: 'shown.bs.tab',
        relatedTarget: $previous[0]
      })
    })
  };
  //激活函数
  Tab.prototype.activate = function (element, container, callback) {
    //参数:目标 包裹容器 执行函数
    var $active    = container.find('> .active');//找到显示的那个
    //  处理动画
    var transition = callback
      && $.support.transition
      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length);

    function next() {
      $active
        .removeClass('active')
        .find('> .dropdown-menu > .active')
          .removeClass('active')
        .end()
        .find('[data-toggle="tab"]')
          .attr('aria-expanded', false)

      element
        .addClass('active')
        .find('[data-toggle="tab"]')
          .attr('aria-expanded', true)

      if (transition) {
        element[0].offsetWidth // reflow for transition
        element.addClass('in')
      } else {
        element.removeClass('fade')
      }

      if (element.parent('.dropdown-menu').length) {
        element
          .closest('li.dropdown')
            .addClass('active')
          .end()
          .find('[data-toggle="tab"]')
            .attr('aria-expanded', true)
      }

      callback && callback()
    }

    $active.length && transition ?
      $active
        .one('bsTransitionEnd', next)
        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
      next();

    $active.removeClass('in')
  };

相关文章

网友评论

      本文标题:Bootstrap插件解析3 切换标签

      本文链接:https://www.haomeiwen.com/subject/ntwnshtx.html