Object-oriented tab bar switching

In the B station to see the video of the learning portal
first look at the results

Insert picture description here

Demand introduction

  1. Click on the tab bar to achieve the switching effect
  2. Click the + sign to add tab items and content items
  3. Click the X number to delete the current tab item and content item
  4. Click on the text or content of the tab item, you can modify the text inside

Extract object: tab object

  1. The object has a switching function
  2. The object has an add function
  3. The object has a modification function
  4. The object has a delete function

Project Analysis

Project initialization

All li section X buttons that have been added should be bound to events

Switch

  • Let the currently clicked li have a class name, and brothers remove the class name
  • When you click li, this points to li, not #tab, so pay attentionthis points to

Add to

  • When you click add, create li and section
  • When you click to add, it is currently selected, brothers remove the class name
  • Add the added to the corresponding parent component

The reason why createElement is not recommended is because there are more li elements.
Element.insertAdjacentHtml() can directly add string format elements to the parent element

  • Each time the addition is completed, new li and section must be retrieved, and new events must be bound
  • When clicked, this points to the + button, pay attentionthis points to

delete

  • When you click X, it may bubble up to the father’s switching event. RememberStop bubbling
  • When X is clicked, he has no index value, but his father has
  • Every time you delete it, get a new element again

edit

  • Double-click to select and change the content

If you double-click, the text will be selected by default. At this time, you need to prohibit double-clicking to select the text
window.getSelection?window.getSelection().removeAllRanges():document.section.empty();

  • Core idea: When you double-click the text, a text box is successfully inside, then go to the focus or press Enter, then assign the value in the text box to the original element
  • Keep the text box selected
  • When we leave the text box, assign the text box to font

Not much to talk about the code

JS

var _that;
class Tab {
    
    
  constructor() {
    
    
    _that=this
    //首先要获取所有的元素,便于添加事件
    this.tab=document.querySelector('#tab');

    this.ul=this.tab.querySelector('ul')
    this.section=this.tab.querySelector('.section')

    this.add=this.tab.querySelector('.add')
    
    this.init()
  }
  updateNode(){
    
    
    //每次操作完成之后,需要从新获取li和section
    this.liList=this.tab.querySelectorAll('li')
    this.sectionList=this.tab.querySelectorAll('section')
    this.xList = this.tab.querySelectorAll('li span')
    this.fontList=this.tab.querySelectorAll('li font')
  }
  init(){
    
    
    //初始化,让所有li X 都绑定事件
    this.updateNode()
    for(var i =0;i<this.liList.length;i++){
    
    
      this.liList[i].index=i
      this.liList[i].onclick=this.toggleTab
      this.xList[i].onclick=this.delTab
      this.fontList[i].ondblclick=this.editTab
      this.sectionList[i].ondblclick=this.editTab
    }
    this.add.onclick=this.addTab
  }
  clearClass(){
    
    
  	//去除类名
    for(var i =0;i<this.liList.length;i++){
    
    
      this.liList[i].className=''
      this.sectionList[i].className=''
    }
  }
  toggleTab(){
    
    
    //点击li的时候this指向为li,不是#tab,所以要注意this指向
    _that.clearClass()
    this.className='liActive'
    _that.sectionList[this.index].className='sectionActive'
  }
  addTab(){
    
    
    //点击的时候,this指向的是+按钮,注意this指向
    //点击添加的时候,创建li和section
    _that.clearClass()//每次点击添加的时候,当前为选中,兄弟去掉类名

    var random=Math.random()
    var li='<li class="liActive"> <font>新选项卡</font> <span>X</span></li>'
    var section='<section class="sectionActive">选项卡'+random+'</section>'

    //把添加的添加到对应的父组件中
    //不推荐使用createElement的原因是因为,li脸的元素比较多
    // element.insertAdjacentHtml() 可以直接讲字符串格式元素添加到父元素中
    _that.ul.insertAdjacentHTML('beforeend',li)
    _that.section.insertAdjacentHTML('beforeend',section)
    //每次添加完成时候,要重新获取到新的li和section,绑定新的事件
    _that.init()
  }
  delTab(e){
    
    
    //点击 X 的时候,可能会冒泡到父亲的切换事件, 阻止冒泡
    e. stopPropagation()
   
    //点击 X 的时候,他没有索引值,但是他的父亲有
    var index=this.parentNode.index
    //点击 X 删除对应索引的 li section
    //remove() 可以直接删除指定的元素
    _that.liList[index].remove()
    _that.sectionList[index].remove()

    //每次删除完,重新获取一遍新的元素
    _that.init()

    //当选中的不是选中状态时,选中状态不变
    if(document.querySelector('.liActive')) return;

    //当删除选中状态的li时,让他的前一个li为选中状态
      index--
    
    //让他前一个li做一次点击事件  
    //第一个的时候,没有前一个,做一个判断
    _that.liList[index] &&  _that.liList[index].click()
   
  }
  editTab(){
    
    
    var str=this.innerHTML  
    //双击选中  改变内容
    // 如果双击的话 会默认选中文字,此时需要禁止双击选中文字
    window.getSelection?window.getSelection().removeAllRanges():document.section.empty();
    //核心思路:双金文字时,里面成功一个文本框,当时去焦点或者摁下回车后,把文本框中的值赋给原先的元素
    this.innerHTML='<input type="text" />'
    var input = this.children[0]
    input.value=str
    //让文本框处于选中状态
    input.select()
    //当我们离开文本框的时候,把文本框的值给了font
    input.onblur=function(){
    
    
      this.parentNode.innerHTML=this.value
    }
    //按下回车的时候,把文本框的值,给了font
    input.onkeyup=function(e){
    
    
      if(e.keyCode===13){
    
    
        //手动调用input失焦事件
        this.blur()
      }
    }
  }

}
new Tab()

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>
    ul{
     
     
      padding: 0;
      margin: 0;
    }
    #tab{
     
     
      width: 600px;
      height: 400px;
      position: relative;
      border: 1px solid pink;
    }
    ul{
     
     
      overflow: hidden;
      border-bottom: 1px solid red;
    }
    ul li{
     
     
      box-sizing: border-box;
      list-style: none;
      height: 50px;
      width: 80px;
      border: 1px solid red;
      float: left;
      position: relative;
      text-align: center;
      line-height: 50px;
    }
    ul li span{
     
     
      position: absolute;
      right: 0;
      top: 0;
      width: 15px;
      height: 15px;
      color: white;
      background: black;
      text-align: center;
      line-height: 15px;
    }
    input{
     
     
      width: 100%;
    }
    section input{
     
     
      height: 100px;
      width: 90%;
    }
    .section{
     
     
      width: 100%;
      height: 350px;
    }
    section{
     
     
      display: none;
      width: 100%;
      height: 100%;
    }
    .add{
     
     
      font-weight: bold;
      position: absolute;
      right: 5px;
      top: 5px;
      border: 1px salmon solid;
      padding: 5px;
    }
    .liActive{
     
     
      background-color: antiquewhite;
    }
    .sectionActive{
     
     
      display: block;
    }
  </style>
</head> 
<body>
  <div id="tab">
    <ul>
      <li class="liActive"> <font>测试1</font> <span>X</span></li>
      <li> <font>测试2</font> <span>X</span></li>
      <li><font>测试3</font> <span>X</span></li>
    </ul>
    <div class="add">+</div>
    <div class="section">
      <section class="sectionActive">li1</section>
      <section>测试2</section>
      <section>测试三</section>
    </div>
  </div>
</body>
<script src="./index.js"></script>
</html>

Guess you like

Origin blog.csdn.net/weixin_45972345/article/details/115052736