方法1(老方法):此方法使用的是排他思想来实现tab栏效果,以及使用一个变量that的方法来解决构造函数中的this指向问题。
<!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.0" />
<title>Document</title>
<style>
.active-btn {
color: red;
}
.con .box {
display: none;
}
.con .active {
display: block;
}
</style>
</head>
<body>
<div class="tab">
<div>
<button class="btn active-btn">新闻</button>
<button class="btn">历史</button>
</div>
<div class="con">
<div class="box active">新闻1新闻1新闻1新闻1新闻1新闻1新闻1</div>
<div class="box">历史1历史1历史1历史1历史 1历史1历史1</div>
</div>
</div>
<script>
function Tab() {
//属性:要使用的东西(也就是面向过程中定义的全局变量)
//方法:要执行的动作
this.init = function() {
//解决方法:定义一个局部变量来保存构造函数创建的tab对象,便于在局部函数中使用到tab对象
this.btns = document.querySelectorAll(".btn");
this.boxs = document.querySelectorAll(".box");
let that = this;
this.btns.forEach(function(v, i) {
v.onclick = function() {
/* console.log(v, i); */
/* 注:此处若用this不是指的是tab对象,因为在事件内部的this是指触发事件的元素
若是在方法内部的this是指创建对象(解决方法如上) */
//方法1:使用排他思想的方法
that.btns.forEach(function(v1) {
v1.style.color = "black";
});
v.style.color = "red";
that.boxs.forEach(function(v2) {
v2.style.display = "none";
});
that.boxs[i].style.display = "block";
};
});
};
this.init();
}
var tab = new Tab();
console.log(tab);
</script>
</body>
</html>
方法2(新方法):使用自定义类名的方法,添加和删除类名来实现tab栏的效果,以及使用ES6新增方法箭头函数来解决构造函数中的this指向问题。
<!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.0" />
<title>Document</title>
<style>
.active-btn {
color: red;
}
.con .box {
display: none;
}
.con .active {
display: block;
}
</style>
</head>
<body>
<div class="tab">
<div>
<button class="btn active-btn">新闻</button>
<button class="btn">历史</button>
</div>
<div class="con">
<div class="box active">新闻1新闻1新闻1新闻1新闻1新闻1新闻1</div>
<div class="box">历史1历史1历史1历史1历史 1历史1历史1</div>
</div>
</div>
<script>
function Tab() {
this.boxs = document.querySelectorAll(".box");
this.btns = document.querySelectorAll(".btn");
this.init = function() {
//console.log(this); //此处的this是指tab对象
this.btns.forEach((v, i) => {
//console.log(this); //此处的this是指window对象 使用箭头函数就失去了自身的this(向上一层看)
v.onclick = () => {
//此处的this是指button按钮 使用箭头函数就失去了自身的this(向上一层看)
this.btns.forEach((v) => v.classList.remove("active-btn"));
v.classList.add("active-btn");
/* console.log(this.boxs); */
this.boxs.forEach((v) => v.classList.remove("active"));
this.boxs[i].classList.add("active");
};
});
};
this.init();
}
var tab = new Tab();
console.log(tab);
</script>
</body>
</html>
总结:
构造方法内部的this---->指构造函数对象
事件内部的this---->指触发事件的元素
匿名函数(作为参数的匿名函数)尽量都写成箭头函数,因为变成箭头函数之后,就失去了自身的this
(箭头函数写法简记:括号左边的function去掉变成右边的箭头)
事件处理函数要不要写成箭头函数看需求