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')
};
网友评论