您当前的位置:易学堂 > 日志记录

JavaScript实现Tab栏切换功能详解

时间:2022-10-24 11:49:10

这篇文章主要介绍了JavaScript实现Tab栏切换的实现方式,是面向对象的写法,本文给大家分享详细案例代码,需要的朋友可以参考下!

1.实现效果

34d8fe32c3cc6cc50e8cc330d1c5e5c5_2022102409100314.gif

2.功能需求

  • 点击tab栏,可以切换效果.

  • 点击+号,可以添加tab项和内容项.

  • 点击x号,可以删除当前的tab项和内容项

  • 双击tab项文字或者内容项文字,可以修改里面的文字内容.

3.抽象对象

抽象对象:Tab对象

  • 该对象具有切换功能

  • 该对象具有添加功能

  • 该对象具有删除功能

  • 该对象具有修改功能

4.切换功能实现

首先把大家可以先看看html结构,防止获取元素和类名的时候不知道获取的是什么:

Js 面向对象 动态添加标签页测试1测试2测试3+测试1测试2测试3

在这一节里我们要实现的效果:

8a4e7fc9c91560added61a260405034c_2022102409100315.gif

示例代码:

var that;
class tab{
constructor(id){
//获取元素
that = this;
this.main = document.querySelector(id);
this.lis = this.main.querySelectorAll('li');
this.sections = this.main.querySelectorAll('section');
this.init();//自动调用init
}
init(){
//init初始化操作让相关元素绑定事件
for(let i = 0;i<this.lis.length;i++){
this.lis[i].setAttribute('index',i);//设置索引值
this.lis[i].onclick = this.toggleTab;
}
}
toggleTab() {
//clearClass函数是类的公共函数,所有只能通过that调用
that.clearClass();
this.className = 'liactive';
that.sections[this.getAttribute('index')].className = 'conactive';
}
clearClass() {
for(var i = 0;i<this.lis.length;i++) {
this.lis[i].className = '';
this.sections[i].className = '';
}
}
}
var newtab = new tab('.tabsbox');

在construcotr里我们要获取相关元素,这里一定要注意this的问题,必须要加this,因为this指向的就是实例化对象。在获取元素后调用init函数,init函数就是用来给元素绑定事件的,比如在页面刷新时tab栏就有了切换添加这些功能,所以要把init函数放在construcotr里。设置索引值是为了在点击tab栏的时候,底下的内容区域也可能够同样变化。

注意:toggleTab()里调用clearClass时是that,而不是this。因为this指向的是调用函数的人,这里指的是li,因为在点击了li时才会调用切换函数。但是li里面没有clearClass方法,所以应该用that,that在这里指向的是实例化对象

5.添加功能实现

1.点击+可以实现添加新的选项卡和内容

2.第一步:创建新的选项卡li和新的内容section

3.第二步:把创建的两个元素追加到对应的父元素中.

4.利用insertAdjacentHTML()可以直接把字符串格式元素添加到父元素中

这里简单介绍一下insertAdjacentHTML()的语法:

position是相对于元素的位置,并且必须是以下字符串之一:

'beforebegin' 元素自身的前面。

'afterbegin' 插入元素内部的第一个子节点之前。

'beforeend' 插入元素内部的最后-个子节点之后。

'afterend' 元素自身的后面。

text是要被解析为HTML或XML,并插入到DOM树中的字符串。

首先我们在construcor里面获取元素:

this.add = this.main.querySelector('.tabadd');
this.ul = this.main.querySelector('.fisrstnav ul');
this.fsection = this.main.querySelector('.tabscon');

然后在init初始化函数里给添加按钮绑定事件:

this.add.onclick = this.addTab;

最后创建添加函数addTab():

addTab() {
that.clearClass();
var random = Math.random();
var li = '新选项卡';
var section = '测试'+ random +'';
that.ul.insertAdjacentHTML('beforeend',li);
that.fsection.insertAdjacentHTML('beforeend',section);
}

在添加函数的开头,要先调用clearClass清除原先的样式,让新添加的选项卡为选中状态,我们先看一下效果:

6d035fbe4081b4eaa7b0369ee1ba6fa2_2022102409100316.gif

为什么新添加的选项卡不能切换,并且以前的li和section没有清除掉类,这是为什么呢?

因为这是我们后来添加的,我们在获取元素的时候是页面加载的时候,后来添加的也就没有被获取元素,所以也就没有绑定点击事件,就会有这些bug。

所以我们应该在点击加号按钮之后,应该重新获取一下所有的li和section,那么我们新建一个更新函数updateNode(),把construcotr里面获取li和section的部分放进去,当我们每次点击添加按钮的时候都再获取一次所有li和section这样bug就解决了

updateNode() {
this.lis = this.main.querySelectorAll('li');
this.sections = this.main.querySelectorAll('section');
}

并且在init开头加上这一句:

this.updateNode();

再在addTab最后加上这句:

that.init();

这样我们每次添加一个新的选项卡和内容时,都会重新获取并且给新添加的绑定事件。

实现效果:

013a77363d91fe5ac61c38a708663bbc_2022102409100317.gif

6.删除功能实现

  • 点击x号可以删除当前的Ii选项卡和当前的section

  • x号是没有索引号的,但是它的父亲li有索引号,这个索引号正是我们想要的索引号

  • 所以核心思路是:点击x号可以删除这个索引号对应的Ii和section

首先我们要获取所有的关闭按钮,那我们应该把获取元素的操作放在construcor里还是updateNode里面呢?

事实上我们必须把获取关闭按钮的步骤放在updateNode里,因为li和关闭按钮是一一对应的,当新添加一个选项卡时,关闭按钮的数量也需要更新

那么我们把这一句放在updateNode里面:

this.remove = this.main.querySelectorAll('.icon-guanbi');

并且在init的for循环里添加点击事件,removeTab就是删除方法:

this.remove[i].onclick = this.removeTab;

我们新建一个删除函数removeTab():

removeTab(e) {
e.stopPropagation();//阻止冒泡 防止触发他的父亲li的切换点击事件
var index = this.parentNode.getAttribute('index');
that.lis[index].remove();
that.fsection[index].remove();
that.init();
}

在函数里首先我们得阻止冒泡,因为点击x号时如果有冒泡也会触发他的父亲li的点击事件。然后我们拿到对应的li的索引号,通过remove方法删除对应的li和section,然后再次获取最新的li和section。

实现效果:

170a554c56b2925f82a3a27173cd62ec_2022102409100418.gif

我们在删除了选中状态的这个li的时候,应该让他的前一个li处于选定状态

我们在removeTab里再添加下面两句:

index--;
that.lis[index] && that.lis[index].click();

因为我们删除了当前的li,想让前一个li处于选定状态,那就得让索引号减一,下面这个&&语句的意思就是。如果当前的li是最后一个,也就是index为0时,那么index--就是负一,这样that.lis[index]就为假就不会执行后面这个语句。后面这句就是手动调用点击事件,这样前一个li就处于选定状态了。

我们还有最后一个功能,就是当删除的不是选中状态的li的时候,原来的选中状态li保持不变就行

我们只需要加上这一句在index--之前:

if(document.querySelector('.liactive')) return;

如果我们删除的不是选中状态的li的时候,就说明有.liactive这个类,那么直接return就不会执行下面的代码了。要是删除的就是选中状态的li,那就不存在.liactive类就执行下面的代码

实现效果:

b81f248d2a47bf35121ff49e89e8ca4c_2022102409100419.gif

这里修改功能就不进行说明了,下面是源码链接:传送门

标签: JavaScript