原生JavaScript实现一个简单的组件化Tab

Tab相信大家都不会陌生,他算是前端开发中最常见的组件之一。接下来我就跟大家分享一个我用原生JavaScript实现的一个简单的组件化Tab。

首先是HTML结构,没什么好说的了吧。

<div id="tab1">
	<ul class="tab-head">
		<li>tab1</li>
		<li>tab2</li>
		<li>tab3</li>
	</ul>
	<div class="tab-panel-wrap">
		<div class="tab-panel">我是面板1</div>
		<div class="tab-panel">我是面板2</div>
		<div class="tab-panel">我是面板3</div>
	</div>
</div>

不加css长这个样。


接下来是css,头部用的是浮动布局,所以有个清除浮动。.tab-panel.active这样连起来的选择器,用意是必须同时拥有这两个类才会触发样式。但是这样写会有IE8的兼容性的问题。不过问题不大。

.tab-head {
	list-style-type: none;
}

/*清除浮动*/
.tab-head::after {
	clear: both;
	content: ' ';
	width: 0;
	height: 0;
	display: block;
}

.tab-head li{
	float: left;
	margin-right: 20px;
	/*手型鼠标*/
	cursor: pointer;
	font-size: 24px;
}

/*选中选项卡*/
/*IE8兼容问题*/
.tab-head li.active {
	color: #188eee;
	cursor: default;
	border-bottom: 1px solid #188eee;
}

.tab-panel-wrap {
	width: 300px;
	height: 100px;
	margin-top: 10px;
}

.tab-panel-wrap .tab-panel {
	width: 100%;
	height: 100%;
	display: none;
	border: 1px solid #188eee;
	font-size: 24px;
}

/*显示对应内容*/
/*IE8兼容问题*/
.tab-panel.active {
	display: block;
}

只是为了说明问题所以有点丑。


重点来了下面是js代码。

/**
 * 定义一个Tab类
 * @param  {String} tabId tab的id
 */
function Tab(tabId) {
	this.init(tabId);
}
/**
 * 入口函数
 * @param  {String} tabId tab的id
 */
Tab.prototype.init = function(tabId) {
	//获取相应DOM
	var tabWrap = this.tabWrap = document.querySelector(tabId);
	this.tabs = tabWrap.querySelectorAll('.tab-head li');
	this.panels = tabWrap.querySelectorAll('.tab-panel-wrap .tab-panel');
	//记录上一次选择的序号
	this.current = 1;

	this.active(0);
	this.event();
};

/**
 * 控制选中效果函数
 * @param  {Number} index 默认显示第几个面板
 */
Tab.prototype.active = function(index) {
	if (index !== this.current) {
		//显示当前
		this.tabs[index].classList.add('active');
		this.panels[index].classList.add('active');
		//结束上一次的选择
		this.tabs[this.current].classList.remove('active');
		this.panels[this.current].classList.remove('active');
		//保存
		this.current = index;
	}
};

/**
 * 监听事件函数
 */
Tab.prototype.event = function() {
	//保存当前this
	var tis = this;
	var len = this.tabs.length;

	for (let i = 0; i < len; i++) {
		//给tab添加监听
		this.tabs[i].addEventListener ('click', function (event) {
			tis.active(i);
		}, false);
	}

};

var tab1 = new Tab('#tab1');
tab1.active(1);


说一下几个核心的地方吧。

①代码中current这个变量目的是保存上一次被选中的tab索引序点击打开链接号,这样做的目的是避免每次在删除active类的时候每个元素都傻乎乎的删个遍,只需要删除上一次被选中的就好了。

②第二个要说的就是event()函数里的var tis = this;因为在绑定事件里面的函数this指向会变所以为了能够调用active()函数,这里需要把执行环境提前保存下来。

还有一个要注意的点就是

for (let i = 0; i < len; i++) {
		//给tab添加监听
		this.tabs[i].addEventListener ('click', function (event) {
			tis.active(i);
		}, false);
	}

这的for循环中一定要用let而不是var,如果用var的话所有事件触发的时候 i 都会是最大值。具体原理可以参考ES6之let(理解闭包)和const命令

以上就是一个简单的Tab全部内容了,如果有什么不足希望大家提出来一起讨论。




猜你喜欢

转载自blog.csdn.net/qq_41418386/article/details/79790684