JavaScript實(shí)現(xiàn)Tab欄切換功能詳解
1.實(shí)現(xiàn)效果
2.功能需求
- 點(diǎn)擊tab欄,可以切換效果.
- 點(diǎn)擊+號(hào),可以添加tab項(xiàng)和內(nèi)容項(xiàng).
- 點(diǎn)擊x號(hào),可以刪除當(dāng)前的tab項(xiàng)和內(nèi)容項(xiàng)
- 雙擊tab項(xiàng)文字或者內(nèi)容項(xiàng)文字,可以修改里面的文字內(nèi)容.
3.抽象對(duì)象
抽象對(duì)象:Tab對(duì)象
- 該對(duì)象具有切換功能
- 該對(duì)象具有添加功能
- 該對(duì)象具有刪除功能
- 該對(duì)象具有修改功能
4.切換功能實(shí)現(xiàn)
首先把大家可以先看看html結(jié)構(gòu),防止獲取元素和類名的時(shí)候不知道獲取的是什么:
<h4> Js 面向?qū)ο?動(dòng)態(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>
在這一節(jié)里我們要實(shí)現(xiàn)的效果:
示例代碼:
var that; class tab{ constructor(id){ //獲取元素 that = this; this.main = document.querySelector(id); this.lis = this.main.querySelectorAll('li'); this.sections = this.main.querySelectorAll('section'); this.init();//自動(dòng)調(diào)用init } init(){ //init初始化操作讓相關(guān)元素綁定事件 for(let i = 0;i<this.lis.length;i++){ this.lis[i].setAttribute('index',i);//設(shè)置索引值 this.lis[i].onclick = this.toggleTab; } } toggleTab() { //clearClass函數(shù)是類的公共函數(shù),所有只能通過that調(diào)用 that.clearClass(); this.className = 'liactive'; that.sections[this.getAttribute('index')].className = 'conactive'; } clearClass() { for(var i = 0;i<this.lis.length;i++) { this.lis[i].className = ''; this.sections[i].className = ''; } } } var newtab = new tab('.tabsbox');
在construcotr里我們要獲取相關(guān)元素,這里一定要注意this的問題,必須要加this,因?yàn)閠his指向的就是實(shí)例化對(duì)象。在獲取元素后調(diào)用init函數(shù),init函數(shù)就是用來給元素綁定事件的,比如在頁面刷新時(shí)tab欄就有了切換添加這些功能,所以要把init函數(shù)放在construcotr里。設(shè)置索引值是為了在點(diǎn)擊tab欄的時(shí)候,底下的內(nèi)容區(qū)域也可能夠同樣變化。
注意:toggleTab()里調(diào)用clearClass時(shí)是that,而不是this。因?yàn)閠his指向的是調(diào)用函數(shù)的人,這里指的是li,因?yàn)樵邳c(diǎn)擊了li時(shí)才會(huì)調(diào)用切換函數(shù)。但是li里面沒有clearClass方法,所以應(yīng)該用that,that在這里指向的是實(shí)例化對(duì)象
5.添加功能實(shí)現(xiàn)
1.點(diǎn)擊+可以實(shí)現(xiàn)添加新的選項(xiàng)卡和內(nèi)容
2.第一步:創(chuàng)建新的選項(xiàng)卡li和新的內(nèi)容section
3.第二步:把創(chuàng)建的兩個(gè)元素追加到對(duì)應(yīng)的父元素中.
4.利用insertAdjacentHTML()可以直接把字符串格式元素添加到父元素中
這里簡單介紹一下insertAdjacentHTML()的語法:
position是相對(duì)于元素的位置,并且必須是以下字符串之一:
'beforebegin' 元素自身的前面。
'afterbegin' 插入元素內(nèi)部的第一個(gè)子節(jié)點(diǎn)之前。
'beforeend' 插入元素內(nèi)部的最后-個(gè)子節(jié)點(diǎn)之后。
'afterend' 元素自身的后面。
text是要被解析為HTML或XML,并插入到DOM樹中的字符串。
首先我們?cè)赾onstrucor里面獲取元素:
this.add = this.main.querySelector('.tabadd'); this.ul = this.main.querySelector('.fisrstnav ul'); this.fsection = this.main.querySelector('.tabscon');
然后在init初始化函數(shù)里給添加按鈕綁定事件:
this.add.onclick = this.addTab;
最后創(chuàng)建添加函數(shù)addTab():
addTab() { that.clearClass(); var random = Math.random(); var li = '<li class="liactive"><span>新選項(xiàng)卡</span><span class="iconfont icon-guanbi"></span></li>'; var section = '<section class="conactive">測試'+ random +'</section>'; that.ul.insertAdjacentHTML('beforeend',li); that.fsection.insertAdjacentHTML('beforeend',section); }
在添加函數(shù)的開頭,要先調(diào)用clearClass清除原先的樣式,讓新添加的選項(xiàng)卡為選中狀態(tài),我們先看一下效果:
為什么新添加的選項(xiàng)卡不能切換,并且以前的li和section沒有清除掉類,這是為什么呢?
因?yàn)檫@是我們后來添加的,我們?cè)讷@取元素的時(shí)候是頁面加載的時(shí)候,后來添加的也就沒有被獲取元素,所以也就沒有綁定點(diǎn)擊事件,就會(huì)有這些bug。
所以我們應(yīng)該在點(diǎn)擊加號(hào)按鈕之后,應(yīng)該重新獲取一下所有的li和section,那么我們新建一個(gè)更新函數(shù)updateNode(),把construcotr里面獲取li和section的部分放進(jìn)去,當(dāng)我們每次點(diǎn)擊添加按鈕的時(shí)候都再獲取一次所有l(wèi)i和section這樣bug就解決了
updateNode() { this.lis = this.main.querySelectorAll('li'); this.sections = this.main.querySelectorAll('section'); }
并且在init開頭加上這一句:
this.updateNode();
再在addTab最后加上這句:
that.init();
這樣我們每次添加一個(gè)新的選項(xiàng)卡和內(nèi)容時(shí),都會(huì)重新獲取并且給新添加的綁定事件。
實(shí)現(xiàn)效果:
6.刪除功能實(shí)現(xiàn)
- 點(diǎn)擊x號(hào)可以刪除當(dāng)前的Ii選項(xiàng)卡和當(dāng)前的section
- x號(hào)是沒有索引號(hào)的,但是它的父親li有索引號(hào),這個(gè)索引號(hào)正是我們想要的索引號(hào)
- 所以核心思路是:點(diǎn)擊x號(hào)可以刪除這個(gè)索引號(hào)對(duì)應(yīng)的Ii和section
首先我們要獲取所有的關(guān)閉按鈕,那我們應(yīng)該把獲取元素的操作放在construcor里還是updateNode里面呢?
事實(shí)上我們必須把獲取關(guān)閉按鈕的步驟放在updateNode里,因?yàn)閘i和關(guān)閉按鈕是一一對(duì)應(yīng)的,當(dāng)新添加一個(gè)選項(xiàng)卡時(shí),關(guān)閉按鈕的數(shù)量也需要更新
那么我們把這一句放在updateNode里面:
this.remove = this.main.querySelectorAll('.icon-guanbi');
并且在init的for循環(huán)里添加點(diǎn)擊事件,removeTab就是刪除方法:
this.remove[i].onclick = this.removeTab;
我們新建一個(gè)刪除函數(shù)removeTab():
removeTab(e) { e.stopPropagation();//阻止冒泡 防止觸發(fā)他的父親li的切換點(diǎn)擊事件 var index = this.parentNode.getAttribute('index'); that.lis[index].remove(); that.fsection[index].remove(); that.init(); }
在函數(shù)里首先我們得阻止冒泡,因?yàn)辄c(diǎn)擊x號(hào)時(shí)如果有冒泡也會(huì)觸發(fā)他的父親li的點(diǎn)擊事件。然后我們拿到對(duì)應(yīng)的li的索引號(hào),通過remove方法刪除對(duì)應(yīng)的li和section,然后再次獲取最新的li和section。
實(shí)現(xiàn)效果:
我們?cè)趧h除了選中狀態(tài)的這個(gè)li的時(shí)候,應(yīng)該讓他的前一個(gè)li處于選定狀態(tài)
我們?cè)趓emoveTab里再添加下面兩句:
index--; that.lis[index] && that.lis[index].click();
因?yàn)槲覀儎h除了當(dāng)前的li,想讓前一個(gè)li處于選定狀態(tài),那就得讓索引號(hào)減一,下面這個(gè)&&語句的意思就是。如果當(dāng)前的li是最后一個(gè),也就是index為0時(shí),那么index--就是負(fù)一,這樣that.lis[index]就為假就不會(huì)執(zhí)行后面這個(gè)語句。后面這句就是手動(dòng)調(diào)用點(diǎn)擊事件,這樣前一個(gè)li就處于選定狀態(tài)了。
我們還有最后一個(gè)功能,就是當(dāng)刪除的不是選中狀態(tài)的li的時(shí)候,原來的選中狀態(tài)li保持不變就行
我們只需要加上這一句在index--之前:
if(document.querySelector('.liactive')) return;
如果我們刪除的不是選中狀態(tài)的li的時(shí)候,就說明有.liactive這個(gè)類,那么直接return就不會(huì)執(zhí)行下面的代碼了。要是刪除的就是選中狀態(tài)的li,那就不存在.liactive類就執(zhí)行下面的代碼
實(shí)現(xiàn)效果:
這里修改功能就不進(jìn)行說明了,下面是源碼鏈接:傳送門
到此這篇關(guān)于JavaScript實(shí)現(xiàn)Tab欄切換功能詳解的文章就介紹到這了,更多相關(guān)JS Tab欄切換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解webpack-dev-server 設(shè)置反向代理解決跨域問題
后端只負(fù)責(zé)接口,前端負(fù)責(zé)數(shù)據(jù)展示、邏輯處理。那么如何跨域?這篇文章主要介紹了webpack-dev-server 設(shè)置反向代理解決跨域問題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04JavaScript 輪播圖和自定義滾動(dòng)條配合鼠標(biāo)滾輪分享代碼貼
本文給大家分享一段js輪播圖和自定義滾動(dòng)條的代碼片段,布局和樣式小編沒給大家多介紹,大家可以根據(jù)個(gè)人需求優(yōu)化,具體實(shí)現(xiàn)代碼,大家可以參考下面代碼片段2016-10-10AjaxUpLoad.js實(shí)現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了AjaxUpLoad.js實(shí)現(xiàn)文件上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03Javascript寫了一個(gè)清除“l(fā)ogo1_.exe”的殺毒工具(可掃描目錄)
Javascript寫了一個(gè)清除“l(fā)ogo1_.exe”的殺毒工具(可掃描目錄)...2007-02-02uniapp小程序項(xiàng)目獲取位置經(jīng)緯度信息
在實(shí)際項(xiàng)目中很多時(shí)候我們需要獲取設(shè)備的位置信息,去展示給客戶,或者以位置信息為參數(shù),繼續(xù)向服務(wù)器獲取一些數(shù)據(jù),這篇文章主要介紹了uni-app如何獲取位置信息(經(jīng)緯度),需要的朋友可以參考下2022-11-11