案例樣式:

anli.png
HTML結(jié)構(gòu):
<main>
<h4>
Js 面向?qū)ο?動態(tài)添加標(biāo)簽頁
</h4>
<div class="tabsbox" id="tab">
<!-- tab 標(biāo)簽 -->
<nav class="fisrstnav">
<ul>
<li class="liactive"><span>測試1</span><span class="iconfont icon-guanbi"></span></li>
<li><span>測試2</span><span class="iconfont icon-guanbi"></span></li>
<li><span>測試3</span><span class="iconfont icon-guanbi"></span></li>
</ul>
<div class="tabadd">
<span>+</span>
</div>
</nav>
<!-- tab 內(nèi)容 -->
<div class="tabscon">
<section class="conactive">測試1</section>
<section>測試2</section>
<section>測試3</section>
</div>
</div>
</main>
JS結(jié)構(gòu):
var that;
class Tab {
constructor(name) {
that = this // 把實例對象的內(nèi)容賦值給that
this.main = document.querySelector(name) // 獲取大盒子
this.add = this.main.querySelector('.tabadd') // 獲取大盒子里面的添加按鈕
this.ul = this.main.querySelector('.fisrstnav ul:first-child') // li 的父元素,獲取ul元素
this.fsection = this.main.querySelector('.tabscon') // section 父元素 tabscon
this.init() // 通過實例化對象調(diào)用此函數(shù)
}
// initialize 初始化(重新加載)
init() {
that.updataNode() // 頁面初始化之后開始獲取這些元素,做綁定事件
// 頁面初始化之后,給相關(guān)的元素的綁定事件
this.add.onclick = this.addTab; // 給加號按鈕添加綁定事件
for (var i = 0; i < this.lis.length; i++) {
// 給每一個li添加一個元素和索引號
this.lis[i].index = i
// 給所有的小li綁定點擊事件; 點擊之后才調(diào)用此函數(shù)
this.lis[i].onclick = this.toggleTab;
// 給所有的關(guān)閉按鈕綁定點擊事件
this.remove[i].onclick = this.removeClass;
// 雙擊事件用 dblclick 綁定
this.spans[i].ondblclick = this.editTab;
this.sections[i].ondblclick = this.editTab;
}
}
updataNode() { // 獲取動態(tài)添加的元素
this.lis = this.main.querySelectorAll('li') // 獲取大盒子里面的li
this.sections = this.main.querySelectorAll('section')
this.remove = this.main.querySelectorAll('.icon-guanbi') // 獲取關(guān)閉按鈕
this.spans = this.main.querySelectorAll('.fisrstnav li span:first-child')
// console.log(spans);
}
// 1.切換模塊
toggleTab() { // 這里面的this 指向lis
// 排他思想,先清除所有樣式
that.clearClassname()
// 點擊哪個li給哪個li添加 類名
this.className = 'liactive'
that.sections[this.index].className = 'conactive'
}
// 清除樣式
clearClassname() {
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].className = ''
this.sections[i].className = ''
}
}
// 2. 添加模塊
addTab() { // 這里面的this 指向 tabadd
that.clearClassname()
// 創(chuàng)建li元素
var random = Math.random() // 獲取一個隨機數(shù)字
var li = ` <li class="liactive"><span>新選項</span><span class="iconfont icon-guanbi"></span></li> `
var section = `<section class="conactive">${random}</section>`
// 把li元素追加到ul里面
// insertAdjacentHTML(position,text)
// 第一個元素是追加元素的位置,第二個元素表示添加的文本內(nèi)容
that.ul.insertAdjacentHTML('beforeend', li)
that.fsection.insertAdjacentHTML('beforeend', section)
that.init() // 添加完元素后,讓頁面重新加載一次
}
// 3. 刪除模塊
removeClass(e) { // this指向關(guān)閉按鈕
e.stopPropagation(); // 阻止冒泡,防止觸發(fā)li的點擊事件
// 獲取他父親的索引號
var index = this.parentNode.index
console.log(index);
// 刪除相對應(yīng)的父元素
that.lis[index].remove()
that.sections[index].remove()
// 刪除完之后再重新調(diào)用渲染一下頁面函數(shù)
that.init()
// 但我們刪除的不是選中狀態(tài)的按鈕時,原來的li保持不變
if (document.querySelector('.liactive')) return
// 當(dāng)我們刪除了選中狀態(tài)時,讓前一個li 處于選中狀態(tài)
index--
// 手動做點擊事件 ;第一數(shù)值為真則調(diào)用第二個函數(shù)
that.lis[index] && that.lis[index].click()
}
// 4. 修改功能
editTab() { // this 指向sapn
// 設(shè)置默認(rèn)文本框樣式
var str = this.innerHTML;
// 雙擊禁止選中文字
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
this.innerHTML = '<input type="text" />'
// 獲取文本框
var input = this.children[0];
input.value = str
// 用戶雙擊之后,讓文本框里面的內(nèi)容處于選中狀態(tài)
input.select()
// 當(dāng)我們離開之后,讓文本框里面的內(nèi)容給span
// onblur 失去焦點
input.onblur = function () { // 這里面的this指向input
this.parentNode.innerHTML = this.value
}
// 按下回車鍵也可以把文本框里面的值給span
input.onkeyup = function (e) {
if (e.keyCode === 13) {
// 手動調(diào)用表單失去焦點事件 不需要鼠標(biāo)離開
this.blur();
}
}
}
}
new Tab('#tab')