js面向对象 动态增删改查tab栏

实现效果

实现效果
点击x 可删除 点击+可新增 点击tab栏可进行切换 双击可修改内容

HTML CSS

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>js面向对象动态添加标签页</title>
  <link rel="stylesheet" href="../css/tab.css">
</head>
<body>
  <main>
    <h3> js面向对象动态添加标签页</h3>
    <div class="tabbox" id="tab">
      <!-- tab -->
      <nav class="firstnav">
        <ul>
          <li class="liactive"><span>测试1</span><span class="off">x</span></li>
          <li ><span>测试2</span><span class="off">x</span></li>
          <li ><span>测试3</span><span class="off">x</span></li>
        </ul>
        <div class="tabadd"> 
         <span>+</span>
        </div>
      </nav>
      <!-- tab内容 -->
      <div class="tabscon">
       <section class="conactive">测试1</section>
       <section>测试2</section>
       <section>测试3</section>
      </div>
    </div>
  </main>
</body>
<script src="../js/tab.js"></script>
</html>

CSS

*{
  margin: 0;
  padding: 0;
}
h3{
  text-align: center;
}
#tab{
width: 800px;
height: 300px;
border:  1px solid black;
margin: 0 auto;


}
.firstnav{
  width: 100%;
  height: 50px;
  /* border:  1px solid black; */
  display: flex;
 justify-content: space-between;
}
.firstnav ul{
  display: flex;
  height: 50px;
}
.firstnav ul li input{
  width: 80%;
}
.tabscon  input{
  width: 100%;
  height: 50px;
}
.tabadd{
  height: 40px;
 line-height: 40px;
 width: 20px;
 padding: 5px;
}
.firstnav ul li {
  list-style: none;
 border-right: 1px solid black;
 border-bottom: 1px solid black;
 height: 40px;
 line-height: 40px;
 width: 70px;
 padding: 5px;
 display: flex;
 justify-content: space-between;
}
.firstnav ul .liactive{
  border-bottom:  1px solid lemonchiffon;
  background-color: lemonchiffon;
}
.tabscon{
  
  padding: 20px;
  background-color: lemonchiffon;
  height: 210px;
  width: 760px;
}
.tabscon section{
  display: none;
}
.tabscon  .conactive{
  display: block;


}

JS

let that 
class Tab{
  constructor(id){
    //保存当前this指向
     that=this
     //查找元素
    this.main= document.querySelector(id)
    this.add=this.main.querySelector('.tabadd')
    this.ul=this.main.querySelector('.firstnav ul:first-child')
    this.tabscon=this.main.querySelector('.tabscon')
    //调用初始化方法
    this.init()
  }
  init(){
    //更新元素个数
    this.updateNode()
    //循环绑定点击事件
    this.add.οnclick=this.addTab
    for (let i = 0; i < this.lis.length; i++) {
      this.lis[i].index=i
      this.lis[i].οnclick=this.toggleTab
      this.remove[i].οnclick=this.removeTab
      //双击事件
      this.spans[i].οndblclick=this.editTab
      this.sections[i].οndblclick=this.editTab
    }
  }
  //点击添加按钮后 元素个数会动态改变
  updateNode(){
    this.lis=this.main.querySelectorAll('li')
    this.sections=this.main.querySelectorAll('section')
    this.remove=this.main.querySelectorAll('.off')
    this.spans=this.main.querySelectorAll('.firstnav li span:first-child')
  }
  //tab栏切换
 toggleTab(){
   that.clearClass()
  //  console.log(this.index);
  this.className='liactive'
  that.sections[this.index].className='conactive'
 }
 //清楚其他li和section的样式
 clearClass(){
   for (let i = 0; i < this.lis.length; i++) {
   this.lis[i].className=''
   this.sections[i].className=''
   }
 }
 //添加tab栏
 addTab(){
   //清楚其他选中样式
  that.clearClass()
  //随机数
   let random =Math.random()
   // 添加的标签 li section
  let li='<li class="liactive"><span>new</span><span class="off">x</span></li>'
  let section ='<section class="conactive">'+random+'</section>'
  //文本解析为HTML元素
  that.ul.insertAdjacentHTML('beforeend',li)
  that.tabscon.insertAdjacentHTML('beforeend',section)
  //重新调用初始化方法
  that.init()
}
//移除tab栏
 removeTab(e){
   //阻止冒泡
   e.stopPropagation();
   //保存父级index值 作为tab栏选中按钮
   let index= this.parentNode.index
  //  删除当前选中元素
  that.lis[index].remove()
  that.sections[index].remove()
  that.init()
  //当前选中元素不为移除元素 直接返回
  if (document.querySelector('.liactive')) return
  //移除元素为最后一个 则自动选择前一个
  index--
  that.lis[index]&&that.lis[index].click()
 }
 //编辑tab栏文字
 editTab(){
   //保存当前内容
   let str =this.innerHTML
   // 双击禁止选中文字
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
//双击替换为输入框
this.innerHTML='<input type="text"/>'
let input =this.children[0]
//当前文字赋值给input框 并保持选中
input.value=str
input.select()
//鼠标移出输入框 保存当前值
input.οnblur=function () {
 this.parentNode.innerHTML= this.value 
}
//回车自动保存
input.οnkeyup=function (e) {
  if (e.keyCode === 13) {
    //手动调用鼠标方法
    this.blur()
  }
}

 }
}
new Tab('#tab')

知识点总结

面向对象开发
双击禁止选择文字

// 双击禁止选中文字
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();

insertAdjacentHTML() 方法将指定的文本解析为 Element 元素,并将结果节点插入到DOM树中的指定位置。它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素。这避免了额外的序列化步骤,使其比直接使用innerHTML操作更快。
DOMString,表示插入内容相对于元素的位置,并且必须是以下字符串之一:
‘beforebegin’:元素自身的前面。
‘afterbegin’:插入元素内部的第一个子节点之前。
‘beforeend’:插入元素内部的最后一个子节点之后。
‘afterend’:元素自身的后面。

element.insertAdjacentHTML(position, text);

阻止冒泡

 e.stopPropagation();

onblur事件 失去焦点

object.onblur=function(){SomeJavaScriptCode};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值