依次往下都是功能都是叠加的
一、tab切换
1.切换演示
2. 切换完整代码
html代码:
<!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>
* {
margin: 0;
padding: 0;
}
.container {
width: 800px;
height: 500px;
margin: 50px auto;
border: 1px solid red;
}
.nav {
height: 50px;
line-height: 50px;
text-align: center;
display: flex;
justify-content: space-between;
align-items: center;
}
.add {
flex: 1;
text-align: right;
border-bottom: 1px solid #000;
}
.add span {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #000;
margin-right: 20px;
}
ul {
display: flex;
}
ul li {
list-style: none;
width: 100px;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
position: relative;
}
ul li img {
position: absolute;
right: 0;
top: 0;
width: 20px;
height: 20px;
}
.content section {
display: none;
}
.content .conShow {
display: block;
}
section {
padding: 20px;
}
/* 导航栏点击之后添加的样式 */
.liactive {
border-bottom: none;
}
</style>
</head>
<body>
<div class="container" id="tab">
<!-- 导航栏部分 -->
<div class="nav">
<ul>
<li class="liactive"><span>栏目1</span><span><img src="./img/close.png" /></span> </li>
<li><span>栏目2</span><span><img src="./img/close.png" /></span></li>
<li><span>栏目3</span><span><img src="./img/close.png" /></span></li>
</ul>
<div class="add">
<span>+</span>
</div>
</div>
<!-- 内容部分 -->
<div class="content">
<section class="conShow">栏目1</section>
<section>栏目2</section>
<section>栏目3</section>
</div>
</div>
<!-- js文件注意位置的放置 -->
<script src="./js/tab.js"></script>
</body>
</html>
js代码:
// 建立Tab对象,切换、添加、删除、修改
var that;
class Tab {
constructor(id) {
// console.log(id);
that = this;
this.main = document.querySelector('#tab');
// 菜单栏
this.lis = this.main.querySelectorAll('li');
// console.log(this.lis);
// 内容栏
this.sections = this.main.querySelectorAll('section');
// console.log(this.sections);
// 调用初始化函数
this.init();
}
// 初始化操作,让相关的元素绑定事件
init() {
// 采用for循环遍历绑定事件
for (var i = 0; i < this.lis.length; i++) {
// console.log(i);
// 把i索引号存给index
this.lis[i].index = i;
// this.lis[i].onclick = function() {
// // 谁调用,this指向谁,目前指向this.lis[i]
// console.log(this.index);
// }
// 点击调用切换功能,函数不能加小括号,如果加了小括号他会直接调用
this.lis[i].onclick = this.toggleTab;
}
}
// 1.切换功能
toggleTab() {
console.log(this.index);
// 排他思想,先全部清掉,谁用谁添加
that.clearClass();
this.className = 'liactive';
that.sections[this.index].className = 'conShow';
}
// 清除tab样式的功能
clearClass() {
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].className = '';
this.sections[i].className = '';
}
}
// 2.添加功能
addTab() {
}
// 3.删除功能
removeTab() {
}
// 4.修改功能
editTab() {
}
}
new Tab('#tab');
二、tab添加
1.点击+可以实现添加新的选项卡和内容
2.第一步:创建新的选项卡li和新的内容section
3.第二步:把创建的两个元素追加到对应的父元素中
4.利用insertAdjacentHTML()可以直接把字符串格式元素添加到父元素中
1.添加演示
2.添加完整代码
html代码:
<!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>
* {
margin: 0;
padding: 0;
}
.container {
width: 800px;
height: 500px;
margin: 50px auto;
border: 1px solid red;
}
.nav {
height: 50px;
line-height: 50px;
text-align: center;
display: flex;
justify-content: space-between;
align-items: center;
}
.addBox {
flex: 1;
text-align: right;
border-bottom: 1px solid #000;
}
.add {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #000;
margin-right: 20px;
}
ul {
display: flex;
}
ul li {
list-style: none;
width: 100px;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
position: relative;
}
ul li img {
position: absolute;
right: 0;
top: 0;
width: 20px;
height: 20px;
}
.content section {
display: none;
}
.content .conShow {
display: block;
}
section {
padding: 20px;
}
/* 导航栏点击之后添加的样式 */
.liactive {
border-bottom: none;
}
</style>
</head>
<body>
<div class="container" id="tab">
<!-- 导航栏部分 -->
<div class="nav">
<ul>
<li class="liactive"><span>栏目1</span><span><img src="./img/close.png" /></span> </li>
<li><span>栏目2</span><span><img src="./img/close.png" /></span></li>
<li><span>栏目3</span><span><img src="./img/close.png" /></span></li>
</ul>
<div class="addBox">
<span class="add">+</span>
</div>
</div>
<!-- 内容部分 -->
<div class="content">
<section class="conShow ">栏目1</section>
<section>栏目2</section>
<section>栏目3</section>
</div>
</div>
<!-- js文件注意位置的放置 -->
<script src="./js/tab.js "></script>
</body>
</html>
js代码:
// 建立Tab对象,切换、添加、删除、修改
var that;
class Tab {
constructor(id) {
// 获取元素
// console.log(id);
that = this;
this.main = document.querySelector('#tab');
// 获取添加按钮
this.add = this.main.querySelector('.add');
// console.log(this.add);
// 获取li的父元素ul
this.ul = this.main.querySelector('.nav>ul');
// console.log(this.ul);
// 获取section的父元素
this.fsection = this.main.querySelector('.content');
// 调用初始化函数
this.init();
}
// 初始化操作,让相关的元素绑定事件
init() {
// 初始化之后调用一下updateNode
this.updateNode();
// 点击调用添加函数
this.add.onclick = this.addTab;
// 采用for循环遍历绑定事件
for (var i = 0; i < this.lis.length; i++) {
// console.log(i);
// 把i索引号存给index
this.lis[i].index = i;
// this.lis[i].onclick = function() {
// // 谁调用,this指向谁,目前指向this.lis[i]
// console.log(this.index);
// }
// 点击调用切换功能,函数不能加小括号,如果加了小括号他会直接调用
this.lis[i].onclick = this.toggleTab;
}
}
// 获取所有的小li和section,为什么要摘出来,因为会在其余地方使用,封装成方法方便
updateNode() {
// 菜单栏
that.lis = this.main.querySelectorAll('li');
// 内容栏
that.sections = this.main.querySelectorAll('section');
}
// 1.切换功能
toggleTab() {
console.log(this.index);
// 排他思想,先全部清掉,谁用谁添加
that.clearClass();
this.className = 'liactive';
that.sections[this.index].className = 'conShow';
}
// 清除li和section样式的功能
clearClass() {
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].className = '';
this.sections[i].className = '';
}
}
// 2.添加功能
addTab() {
// 先清除
that.clearClass();
var random = Math.random();
// 1.第一步:创建新的选项卡li和新的内容section
var li = '<li class="liactive"><span>新选项卡</span><span><img src="./img/close.png" /></span></li>';
var section = '<section class="conShow ">新内容' + random + '</section>';
// 2.第二步:把创建的两个元素追加到对应的父元素中,利用insertAdjacentHTML()可以直接把字符串格式元素添加到父元素中
that.ul.insertAdjacentHTML('beforeend', li);
that.fsection.insertAdjacentHTML('beforeend', section);
// 当点击添加之后要进行初始化
that.init();
}
// 3.删除功能
removeTab() {
}
// 4.修改功能
editTab() {
}
}
new Tab('#tab');
三、tab删除
1.删除演示
2.删除完整代码
1.点击x可以删除当前的Ii选项卡和当前的section
2.X是没有索引号的,但是它的父亲li有索引号,这个索|号正是我们想要的索引号
3.所以核心思路是:点击x号可以删除这个索引|号对应的li和section
html代码:
<!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>
* {
margin: 0;
padding: 0;
}
.container {
width: 800px;
height: 500px;
margin: 50px auto;
border: 1px solid red;
}
.nav {
height: 50px;
line-height: 50px;
text-align: center;
display: flex;
justify-content: space-between;
align-items: center;
}
.addBox {
flex: 1;
text-align: right;
border-bottom: 1px solid #000;
}
.add {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #000;
margin-right: 20px;
}
ul {
display: flex;
}
ul li {
list-style: none;
width: 100px;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
position: relative;
}
ul li img {
position: absolute;
right: 0;
top: 0;
width: 20px;
height: 20px;
}
.content section {
display: none;
}
.content .conShow {
display: block;
}
section {
padding: 20px;
}
/* 导航栏点击之后添加的样式 */
.liactive {
border-bottom: none;
}
</style>
</head>
<body>
<div class="container" id="tab">
<!-- 导航栏部分 -->
<div class="nav">
<ul>
<li class="liactive"><span>栏目1</span><img src="./img/close.png" class="close" /></li>
<li><span>栏目2</span><img src="./img/close.png" class="close" /></li>
<li><span>栏目3</span><img src="./img/close.png" class="close" /></li>
</ul>
<div class="addBox">
<span class="add">+</span>
</div>
</div>
<!-- 内容部分 -->
<div class="content">
<section class="conShow ">栏目1</section>
<section>栏目2</section>
<section>栏目3</section>
</div>
</div>
<!-- js文件注意位置的放置 -->
<script src="./js/tab.js "></script>
</body>
</html>
js代码:
// 建立Tab对象,切换、添加、删除、修改
var that;
class Tab {
constructor(id) {
// 获取元素
that = this;
this.main = document.querySelector('#tab');
// 获取添加按钮
this.add = this.main.querySelector('.add');
// 获取li的父元素ul
this.ul = this.main.querySelector('.nav>ul');
// 获取section的父元素
this.fsection = this.main.querySelector('.content');
// 调用初始化函数
this.init();
}
// 初始化操作,让相关的元素绑定事件
init() {
// 初始化之后调用一下updateNode
this.updateNode();
// 点击调用添加函数
this.add.onclick = this.addTab;
// 采用for循环遍历绑定事件
for (var i = 0; i < this.lis.length; i++) {
// 把i索引号存给index
this.lis[i].index = i;
// 点击调用切换功能,函数不能加小括号,如果加了小括号他会直接调用
this.lis[i].onclick = this.toggleTab;
// 在循环里面给每个删除按钮添加事件,点击调用删除功能
this.remove[i].onclick = this.removeTab;
}
}
//因为我们动态添加元素,需要重新获取对应的元素并且给其添加事件
updateNode() {
// 菜单栏
that.lis = this.main.querySelectorAll('li');
// 内容栏
that.sections = this.main.querySelectorAll('section');
// 获取所有删除按钮
this.remove = this.main.querySelectorAll('.close');
}
// 1.切换功能
toggleTab() {
// 排他思想,先全部清掉,谁用谁添加
that.clearClass();
this.className = 'liactive';
that.sections[this.index].className = 'conShow';
}
// 清除li和section样式的功能
clearClass() {
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].className = '';
this.sections[i].className = '';
}
}
// 2.添加功能
addTab() {
// 先清除
that.clearClass();
var random = Math.random();
// 1.第一步:创建新的选项卡li和新的内容section
var li = '<li class="liactive"><span>新选项卡</span><img src="./img/close.png" class="close"/></li>';
var section = '<section class="conShow ">新内容' + random + '</section>';
// 2.第二步:把创建的两个元素追加到对应的父元素中,利用insertAdjacentHTML()可以直接把字符串格式元素添加到父元素中
that.ul.insertAdjacentHTML('beforeend', li);
that.fsection.insertAdjacentHTML('beforeend', section);
// 当点击添加之后要进行初始化
that.init();
}
// 3.删除功能
removeTab(e) {
// 阻止冒泡,防止触发li的切换功能
e.stopPropagation();
// 获取当前删除按钮父元素li的索引号,以便删除某个
var index = this.parentNode.index;
console.log(index);
// 根据索引号删除对应的li和section remove( )方法可以直接删除指定的元素
that.lis[index].remove();
that.sections[index].remove();
that.init();
// 当我们删除非选中状态的1i的时候,原来的选中状态li保持不变
// 如果剩下的li不存在liactive样式,我就不执行后面代码,否则
if (document.querySelector('.liactive')) return;
// 当我们删除了选中状态的这个li的时候,让它的前一个li处于选定状态
index--; //上一个
// 手动调用我们的点击事件 不需要鼠标触发,&&的作用是进行判断
//如果前面为真,则执行后面,否则不执行,当前面index为-1时,不再执行,不报错
that.lis[index] && that.lis[index].onclick();
}
// 4.修改功能
editTab() {
}
}
new Tab('#tab');
四、tab修改
1.双击选项卡li或者section里面的文字,可以实现修改功能
2.双击事件是: ondblclick
3.如果双击文字会默认选定文字,此时需要双击禁止选中文字
4.window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();// 双击禁用选中文字
5.核心思路:双击文字的时候,在里面生成一个文本框,当失去焦点或者按下回车然后把文本框输入的值给原先
元素即可
1.修改演示
2.修改完整代码
html代码:
<!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>
* {
margin: 0;
padding: 0;
}
.container {
width: 800px;
height: 500px;
margin: 50px auto;
border: 1px solid red;
}
.nav {
height: 50px;
line-height: 50px;
text-align: center;
display: flex;
justify-content: space-between;
align-items: center;
}
.addBox {
flex: 1;
text-align: right;
border-bottom: 1px solid #000;
}
.add {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #000;
margin-right: 20px;
}
ul {
display: flex;
}
ul li {
list-style: none;
width: 100px;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
position: relative;
}
ul li img {
position: absolute;
right: 0;
top: 0;
width: 20px;
height: 20px;
}
.content section {
display: none;
}
.content .conShow {
display: block;
}
section {
padding: 20px;
}
/* 导航栏点击之后添加的样式 */
.liactive {
border-bottom: none;
}
.nav input {
width: 82%;
height: 30px;
}
.content input {
width: 100%;
height: 200px;
}
</style>
</head>
<body>
<div class="container" id="tab">
<!-- 导航栏部分 -->
<div class="nav">
<ul>
<li class="liactive"><span>栏目1</span><img src="./img/close.png" class="close" /></li>
<li><span>栏目2</span><img src="./img/close.png" class="close" /></li>
<li><span>栏目3</span><img src="./img/close.png" class="close" /></li>
</ul>
<div class="addBox">
<span class="add">+</span>
</div>
</div>
<!-- 内容部分 -->
<div class="content">
<section class="conShow ">栏目1</section>
<section>栏目2</section>
<section>栏目3</section>
</div>
</div>
<!-- js文件注意位置的放置 -->
<script src="./js/tab.js "></script>
</body>
</html>
js代码:
// 建立Tab对象,切换、添加、删除、修改
var that;
class Tab {
constructor(id) {
// 获取元素
that = this;
this.main = document.querySelector('#tab');
// 获取添加按钮
this.add = this.main.querySelector('.add');
// 获取li的父元素ul
this.ul = this.main.querySelector('.nav>ul');
// 获取section的父元素
this.fsection = this.main.querySelector('.content');
// 调用初始化函数
this.init();
}
// 初始化操作,让相关的元素绑定事件
init() {
// 初始化之后调用一下updateNode
this.updateNode();
// 一行最多容纳七个栏目
// 点击调用添加函数
this.add.onclick = this.addTab;
// 采用for循环遍历绑定事件
for (var i = 0; i < this.lis.length; i++) {
// 把i索引号存给index
this.lis[i].index = i;
// 点击调用切换功能,函数不能加小括号,如果加了小括号他会直接调用
this.lis[i].onclick = this.toggleTab;
// 在循环里面给每个删除按钮添加事件,点击调用删除功能
this.remove[i].onclick = this.removeTab;
// 给每一个span绑定双击事件,调用修改功能
this.spans[i].ondblclick = this.editTab;
// 给每一个内容栏绑定双击事件,调用修改功能
this.sections[i].ondblclick = this.editTab;
}
if (that.lis.length >= 7) {
console.log("最多七个栏目");
that.add.onclick = null; //删除事件处理程序
}
}
//因为我们动态添加元素,需要重新获取对应的元素并且给其添加事件
updateNode() {
// 菜单栏
this.lis = this.main.querySelectorAll('li');
// 内容栏
this.sections = this.main.querySelectorAll('section');
// 获取所有删除按钮
this.remove = this.main.querySelectorAll('.close');
//编辑操作 获取所有span
this.spans = this.main.querySelectorAll('.nav li span');
// console.log(this.spans);
}
// 1.切换功能
toggleTab() {
// 排他思想,先全部清掉,谁用谁添加
that.clearClass();
this.className = 'liactive';
that.sections[this.index].className = 'conShow';
}
// 清除li和section样式的功能
clearClass() {
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].className = '';
this.sections[i].className = '';
}
}
// 2.添加功能
addTab() {
// 先清除
that.clearClass();
var random = Math.random();
// 1.第一步:创建新的选项卡li和新的内容section
var li = '<li class="liactive"><span>新选项卡</span><img src="./img/close.png" class="close"/></li>';
var section = '<section class="conShow ">新内容' + random + '</section>';
// 2.第二步:把创建的两个元素追加到对应的父元素中,利用insertAdjacentHTML()可以直接把字符串格式元素添加到父元素中
that.ul.insertAdjacentHTML('beforeend', li);
that.fsection.insertAdjacentHTML('beforeend', section);
// 当点击添加之后要进行初始化
that.init();
}
// 3.删除功能
removeTab(e) {
// 阻止冒泡,防止触发li的切换功能
e.stopPropagation();
// 获取当前删除按钮父元素li的索引号,以便删除某个
var index = this.parentNode.index;
console.log(index);
// 根据索引号删除对应的li和section remove( )方法可以直接删除指定的元素
that.lis[index].remove();
that.sections[index].remove();
that.init();
// 当我们删除非选中状态的1i的时候,原来的选中状态li保持不变
// 如果剩下的li不存在liactive样式,我就不执行后面代码,否则
if (document.querySelector('.liactive')) return;
// 当我们删除了选中状态的这个li的时候,让它的前一个li处于选定状态
index--; //上一个
// 手动调用我们的点击事件 不需要鼠标触发,&&的作用是进行判断
//如果前面为真,则执行后面,否则不执行,当前面index为-1时,不再执行,不报错
that.lis[index] && that.lis[index].onclick();
}
// 4.修改功能
editTab() {
// 先获取原先的内容,之后要用
var str = this.innerHTML;
// 获取内容栏原先内容
console.log(str);
// 双击禁用选中文字
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
// 生成一个文本框 外单内双
this.innerHTML = '<input type="text" />'
// input是span的第一个孩子,所以写法是:
var input = this.children[0];
input.value = str;
input.select(); //文本框里面的值处于选中状态
// 文本框失焦后,把文本框的值赋给span
input.onblur = function() {
this.parentNode.innerHTML = this.value
};
// 按下回车也可以把文本框的值给span
// 键盘事件有事件对象,事件对象里面有keyCode,可以根据keyCode判断按的什么键
input.onkeyup = function(e) {
// console.log(e);
if (e.keyCode == 13) {
// 说明点击的是回车键
// 直接手动调用上方的表单失焦事件
this.blur();
}
}
}
}
new Tab('#tab');