在你书写 构造函数 和 原型内容 的时候
+ 脑海中需要始终想象着未来实例的样子
+ 只要你书写了 this.xxx = yyy
=> 就是在向实例身上添加一个 xxx 成员, 值是 yyy
+ 只要你访问了 this.xxx
=> 就是在访问 实例对象 身上的 xxx
// 是否需要参数
// 至少需要一个参数, 你出现选项卡的范围元素
function Tabs(select, type = 'click') {
// 第一个属性, 选项卡的范围元素
this.ele = document.querySelector(select)
// 1. 获取实现选项卡需要用到的属性
// btns 和 boxs
// 是整个页面范围内的吗 ? 就是和这个 this.ele 元素下的 ul 下的 li
this.btns = this.ele.querySelectorAll('ul > li')
this.boxs = this.ele.querySelectorAll('ol > li')
this.type = type
// 这个位置的 this 是谁 ?
// 当前实例
this.init()
}
// 2. 需要一个方法
// 作用: 给 实例对象 身上的 btns 内的每一个 li 绑定点击事件
// 既然是方法, 最好书写在 prototype 上
Tabs.prototype.init = function () {
// 2-1. 循环遍历 this.btns
this.btns.forEach((item, index) => {
item.addEventListener(this.type, () => {
// 2-2. 给 this.btns 和 this.boxs 内的每一个 li 取消类名
for (let i = 0; i < this.btns.length; i++) {
this.btns[i].className = this.boxs[i].className = ''
}
// 2-3. 给 index 对应的添加类名
this.btns[index].className = this.boxs[index].className = 'active'
})
})
}
//调用
new Tabs('#box', 'click')
new Tabs('#box2', 'mouseover')
new Tabs('#box3')
<div class="box" id="box">
<ul>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<ol>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ol>
</div>
<div class="box" id="box2">
<ul>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<ol>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ol>
</div>
* {
margin: 0;
padding: 0;
}
.box {
width: 600px;
height: 350px;
border: 10px solid pink;
margin: 30px auto;
display: flex;
flex-direction: column;
}
.box > ul {
height: 80px;
display: flex;
}
.box > ul > li {
flex: 1;
background-color: skyblue;
color: #fff;
font-size: 34px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.box > ul > li.active {
background-color: orange;
}
.box > ol {
flex: 1;
position: relative;
}
.box > ol > li {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
display: none;
justify-content: center;
align-items: center;
background-color: purple;
color: #fff;
font-size: 100px;
}
.box > ol > li.active {
display: flex;
}