// 功能需求:
// 1.点击tab栏,可以切换效果.
// 2.点击+号,可以添加tab项和内容项.
// 3.点击x号,可以删除当前的tab项和内容项.
// 4.双击tab项文字或者内容项文字可以修改里面的文字内容.
// step1:抽取共用方法和属性
// 抽象对象: Tab对象
// 1.该对象具有切换功能
// 2.该对象具有添加功能
// 3.该对象具有删除功能
// 4.该对象具有修改功能
var that;
class Tab {
constructor(id) {
that = this;
// 获取元素
this.main = document.querySelector(id);
this.add = this.main.querySelector('.tabadd');
// li的父元素
this.ul = this.main.querySelector('.firstnav ul:first-child');
// section的父元素
this.fsection = this.main.querySelector('.tabscon');
this.init();
}
// 为了解决添加新的元素没有点击效果和状态显示异常的问题,新建一个新的方法
// 获取所有的小li 和section
updateNode(){
this.lis = this.main.querySelectorAll('li'); //获取所有li
this.section = this.main.querySelectorAll('section');//获取下面的所有section
// 获取所有关闭按钮
this.remove = this.main.querySelectorAll('.icon-error');
this.spans = this.main.querySelectorAll('.firstnav li span:first-child');
}
// init 初始化操作让相关的元素绑定事件
init(){
this.updateNode();
this.add.onclick = this.addTab;
for(var i = 0; i< this.lis.length;i++){
this.lis[i].index = i;//给每个li添加索引
//给每个li添加点击事件
this.lis[i].onclick = this.toggleTab;
this.remove[i].onclick = this.removeTab;
this.spans[i].ondbclick = this.editTab;
// 效果是一样的,可以直接使用(双击修改内容)
this.sections[i].ondbclick = this.editTab;
}
}
// 1.切换功能
toggleTab(){
that.clearClass(); //清除所有再设置更改的那一条
this.className = 'liactive'; //this指向单个li
that.sections[this.index].className = 'conactive'; //获取实例对象的sections
}
// 清除所有li和section的样式
clearClass(){
for(var i = 0;i<this.lis.length;i++){
this.lis[i].className = '';
this.section[i].className = '';
}
}
// 2.添加功能
// 第一步:创建新的选项卡li和新的内容section
// 第二步:把创建的两个元素追加到对应的父元素中.
addTab(){
// 先所有class表现状态的都清除掉,再去添加新的
that.clearClass();
// 设置一个随机数看看是不是每次创建都是不一样的
var random = Math.random();
// (1) 创建li元素和section元素
var li = '<li class="liactive"><span>新选项卡</span><i class="iconfont icon-error"></i></li>'
// section跟着一起添加
var section = '<section class="conactive">测试 ' + random +'</section>'
// (2) 把这两个元素追加到对应点父元素里面
// appendChild方法需要创建新节点元素再添加,而这个方法可以通过字符串的形式添加html,更快捷方便
that.ul.insertAdjacentHTML('beforeend',li);
that.init(); //每次添加新标签都要重新获取之前以及现在的li和section的所有内容
}
// 3.删除功能
removeTab(){
e.stopPropagation();//阻止冒泡 防止触发li的切换点击事件
//获取按钮所在的li的下标
var index = this.parentNode.index;
//根据索引号删除对应的li和section
that.lis[index].remove();
that.sections[index].remove();
//重新执行获取事件
that.init();
// 当前我们删除的不是选中状态的li 的时候,原来的选中状态li保持不变
if(document.querySelector('.liactive')) return; //return 下面的代码不再执行
// 当我们删除了选中状态的这个li 的时候,让它的前一个li处于选定状态
index--;
// 直接执行点击事件来切换删除后保留最后一个的状态
// 删除到仅剩一个的时候,index会被修改为-1,这个是无法获取的。
// 我们这里有巧思妙招:(前面为真,则执行后面的程序,为假,则不执行。不需要if来判断)
that.lis[index] && that.lis[index].cilck();
}
// 4.修改功能
// 双击选项卡li或者section里面的文字,可以实现修改功能
// 双击事件是:ondbclick
// 如果双击文字,会默认选定文字,此时需要双击禁止选中文字
// 代码如下:
// window.getSelection ? window.getSelection().removeAllRanges():document.selection.empty();
// 失去焦点和回车都可以编辑成功修改
editTab(){
var str = this.innnerHTML;
// 双击禁止选定文字
window.getSelection ? window.getSelection().removeAllRanges():document.selection.empty();
// 双击tab文字生成一个文本框
this.innnerHTML = '<input type="txet" />';
var input = this.children[0];
input.value = str;
input.select(); // 文本框里面的文字处于选定状态
// 当我们离开文本框就把文本框里面的值传给span
input.onblur = function(){
this.parentNode.innnerHTML = this.value;
}
// 按下回车也可以把文本框里面的值给span
input.onkeyup = function(e){
if(e.keyCode === 13){
// 手动调用表单失去焦点事件 不需要鼠标离开操作
this.blur();
}
}
}
}
var tab = new Tab('#tab'); //执行的时候立即执行constructor的函数
第一课:面向对象案例:tab切换(2021/4/13)(最新补充功能:编辑的保存和回车保存)
最新推荐文章于 2023-12-04 08:53:01 发布
本文详细介绍了使用JavaScript实现选项卡切换、添加、删除和修改功能的代码实现。通过创建Tab类,实现了点击tab切换效果、点击加号添加tab项和内容、点击x号删除tab项及其内容,以及双击修改tab和内容文字的功能。整个过程通过事件绑定和DOM操作完成,提供了良好的交互体验。
摘要由CSDN通过智能技术生成