JavaScript学习笔记—面向对象版tab栏切换
功能需求:
- 点击tab栏,可以切换效果。
- 点击 + 号,可以添加tab项和内容项。
- 点击 x 号,可以删除当前的tab项和内容项。
- 双击tab项文字或者内容项文字,可以修改里面的文字内容。
抽象对象:Tab对象
- 该对象具有切换功能
- 该对象具有添加功能
- 该对象具有删除功能
- 该对象具有修改功能
步骤一:切换功能
代码段:
// 1.切换功能
toggleTab(){
// console.log(this.index);
that.clearClass(); //干掉所有人
this.className='liactive';
that.sections[this.index].className='conactive';
}
clearClass(){
for(var i=0;i<this.lis.length;i++){
this.lis[i].className='';
this.sections[i].className='' // 这边可以使用this 是因为它是被that调用 就是被实例所调用
}
}
步骤二:添加功能
- 点击 + 可以实现添加新的选项卡和内容
- 第一步:创建新的选项卡 li 和新的内容 section
- 第二步:把创建的两个元素追加到对应的父元素中
- 以前的做法:动态创建元素 creatElement,但是元素里面内容较多,需要innerHTML赋值,再appendChild追加到父元素里面
- 现在高级做法:利用insertAdjacentHTML()可以直接把字符串格式元素添加到父元素中
- 区分:appendChild 不支持追加字符串的子元素,insertAdjacentHTML 支持追加字符串的子元素。
注意:
1.因为我们是动态添加元素,需要重新获取对应的元素
2.添加后该方法里需要调用init(),重新获取
(不然lis仍会是一开始初始化的长度,添加的长度没有追加上去。)
代码段:
// 2.添加功能
addTab(){
that.clearClass();
// alert('11');
// (1)创建li元素和section元素
// var li = "<li class="liactive"><span>选项卡</span><span class="iconfont icon-guanbi"></span></li>"
// var section = "<section>测试1</section>"
// (2)把这两个元素追加到对应的父元素里面
that.ul.insertAdjacentHTML('beforeend','<li class="liactive"><span>选项卡</span><span class="iconfont icon-guanbi"></span></li>');
that.fsection.insertAdjacentHTML('beforeend','<section class="conactive">测试145</section>'); //这边要用that啊!因为是+号调用的该方法,+号没有ul、section,
// 所以要用到实例的东西 所以用that
//
that.init();
}
步骤三:删除功能
分析:
- 点击 x 可以删除当前的选项卡和当前的section
- x 是没有索引号的,但是它的父亲 li 有索引号,这个索引号正是我们需要的索引号
- 所以核心思路是:点击x号可以删除这个索引号对应的li 和section
- 获取删除按钮
- 绑定事件
- 根据索引号删除对应的li 和 section
- 当我们删除了选中状态的这个li 的时候,让他的前一个li 处于选中状态
- 当我们删除的不是选中状态时 直接删除就可以 所以添加一个判断条件
注意:
1.要先防止冒泡
2.remove()方法可以直接删除指定的元素
3.if(document.querySelector(’.liactive’)) return;
4.that.lis[index]&&that.lis[index].click();
代码段:
// 3.删除功能
removeTab(e){
e.stopPropagation();//阻止冒泡 防止触发li的点击事件
// alert('11');
var index=this.parentNode.index;
//根据索引号删除对应的li 和 section remove()方法可以直接删除指定的元素
that.lis[index].remove();
that.sections[index].remove();
that.init();
//当我们删除的不是选中状态的li的时候,原来的选中状态保持不变
if(document.querySelector('.liactive')) return;
// 当我们删除了选中状态的这个li 的时候,让他的前一个li 处于选中状态
index--;
that.lis[index]&&that.lis[index].click();
}
步骤四:编辑功能
- 双击选项卡li或者section里面的文字,可以实现修改功能
- 双击事件是:ondblclick
- 如果双击文字,会默认选定文字,此时需要双击禁止选中中文
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
(不用记,用的时候查一下就可以)- 核心思路:双击文字的时候,在里面生成一个文本框,当失去焦点或者按下回车然后把文本框输入的值给原先元素即可
- 先将放文字的标签获取过来→绑定事件→双击禁止选中中文→双击生成一个文本框→将span中的值放入text中,且为选中状态→当失去焦点或者按下回车然后把文本框输入的值给原先元素即可→section部分绑定事件
代码段:
editTab(){
var str=this.innerHTML;// (1)这个this指span标签(调用该方法的标签);(2)this!这样获取文字的昂。
// alert('11');
// console.log('88');
// 双击禁止选定文字
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
this.innerHTML='<input type="text">';
var input=this.children[0];//span标签下的第一个孩子是input
input.value=str;
input.select();//文本框里面的文字处于选定状态
input.onblur=function(){
this.parentNode.innerHTML=this.value;
}
input.onkeyup=function(e){
if(e.keyCode===13){
//手动调用表单失去焦点事件 不需要鼠标离开操作
this.blur();//this!
}
}
//section部分
//只要绑定就可以了
}
其他部分:
构造函数:
var that;
class Tab{
constructor(id){
that=this;
// 获取元素
this.main=document.querySelector(id);
//li的父元素
this.ul=this.main.querySelector('.firstnav ul:first-child');
//section的父元素
this.fsection=this.main.querySelector('.tabscon');
this.add=this.main.querySelector('.tabadd');
this.init();
}
初始化
init(){
this.updateNode();
// init 初始化操作让相关元素绑定事件
for(var i=0;i<this.lis.length;i++){
this.lis[i].index=i;
this.lis[i].onclick=this.toggleTab;
this.removes[i].onclick=this.removeTab;
this.spans[i].ondblclick=this.editTab;
this.sections[i].ondblclick=this.editTab;
}
this.add.onclick=this.addTab;
}
需要从新获取对应的元素
//动态添加的元素 需要从新获取对应的元素
updateNode(){
this.lis=this.main.querySelectorAll('li');
this.sections=this.main.querySelectorAll('section');
this.removes=this.main.querySelectorAll('.icon-guanbi');
this.spans=this.main.querySelectorAll('.firstnav li span:first-child');
}
Learning form pink老师