本篇介紹常用的tab切換功能,使用js、jq、Vue3如何做到,以及說明若一個版面會出現一個以上需要切換時,該注意什麼?
還記的我們在<第15車廂-data-*的坑?data-*介紹篇>,已經介紹了抓去data-*的用法,接著我們就要透過data-*
來實作時常用的tab切換功能
囉!(畫面陽春版喔)
▼ 完成圖
注意
data-tablink="*"
的內容是對應下方tab內容的id="*"
<div class="tab-demo">
<!-- tab標籤列 -->
<ul class="tab-title">
<li class="active">
<a href="javascript:;" data-tablink="one">tab1</a>
</li>
<li>
<a href="javascript:;" data-tablink="two">tab2</a>
</li>
<li>
<a href="javascript:;" data-tablink="three">tab3</a>
</li>
</ul>
<!-- tab內容 -->
<div class="tab-inner-wrap">
<div id="one" class="tab-inner">
<!-- tab1的內容 -->
內容1 內容1 內容1 內容1
</div>
<div id="two" class="tab-inner">
<!-- tab2的內容 -->
內容2
</div>
<div id="three" class="tab-inner">
<!-- tab3的內容 -->
內容3
</div>
</div>
</div>
...第二組
注意
li > a 原本是灰色
,li.active> a 則是加上藍色
.tab-demo {
padding: 20px;
}
.tab-title {
display: flex; // 將li 排列再一起
}
.tab-title li {
padding: 10px;
}
.tab-title li a {
display: block;
padding: 10px;
color: #333;
background-color: #ccc;
text-decoration: none;
}
.tab-title li.active a {
color: #fff;
background-color: #0071bc;
}
.tab-inner {
padding: 10px;
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
目標:需做到按到哪個li就秀出對應的內容
siblings()
是返回被選元素的所有同級元素。
$(document).ready(function () {
tabCutover1();
});
function tabCutover1() {
//抓出li.active的data-tablink的內容;例如是"one"
var tablink = $(".tab-title li.active").find("a").data("tablink");
//將$("#one").顯示,而其他兄弟們(叫做.tab-inner)都隱藏
$('#'+ tablink).show().siblings(".tab-inner").hide();
//當tab標題li被點到時,
$(".tab-title li").click(function () {
//抓出當下被點到的data-tablink的內容;例如是"Two",將$("#Two").顯示,而其他兄弟們(叫做.tab-inner)都隱藏
$('#'+$(this).find("a").data("tablink")).show().siblings(".tab-inner").hide();
//抓出當下被點到的li要加上active(藍色),其他li則要刪除active(藍色)
$(this).addClass("active").siblings(".active").removeClass("active");
});
}
▲好我們先停一下,看一下上方的code
看起來好像沒問題?但是呢,發現第1個tab畫面正常,第2個畫面tab內容卻都沒隱藏了,這是為什麼呢?
主要因為,
$(".tab-title li.active").find("a").data("tablink");
只能叫出符合的第一個$(".tab-title li.active")
元素目前有2個才對/*tab 收合*/
function tabCutover() {
$(".tab-title li.active").each(function () {
var tablink = $(this).find("a").data("tablink");
$('#'+tablink).show().siblings(".tab-inner").hide();
});
$(".tab-title li").click(function () {
$('#'+$(this).find("a").data("tablink")).show().siblings(".tab-inner").hide();
$(this).addClass("active").siblings(".active").removeClass("active");
});
}
這樣就解決啦!
附上JQ版切換程式碼
那...我們以上面邏輯用JS寫寫看(也太難寫了吧!)
HTML及CSS同上喔
我好像是第一次改寫JS...JS找節點實在不是很熟
▼ 主要是因為JS沒有siblings()找兄弟功能,要寫可能要寫很長,所以我只好寫成先叫大家都清除,在叫點出來的串供!
JS
const tabTitle = document.querySelectorAll(".tab-title li");
const tabInner = document.querySelectorAll(".tab-inner");
//tab內容大家都清除
tabInner.forEach(function (item) {
item.style.display = "none";
});
//所有tab區域是active 抓出他data-tablink後 例如是"one" 就可以指定document.getElementById("one")將tab內容顯示
document.querySelectorAll(".tab-title li.active").forEach(function (item) {
let tablink = item.querySelector("a").getAttribute("data-tablink");
document.getElementById(tablink).style.display = "block";
});
//tab-title每個li做監聽 當click時
tabTitle.forEach(function (item) {
item.addEventListener("click", function () {
//抓出click那個元素的a的tablink,例如是"two"
let tablink = item.querySelector("a").getAttribute("data-tablink");
//先找到該父層將所有子層li 移除active的classname(藍色)
item.parentNode.querySelectorAll("li").forEach(function (item) {
item.classList.remove("active");
});
//在將click那個li加回active的classname(藍色)
item.classList.add("active");
//將剛剛抓出來的,例如是"two" >document.getElementById("two")的父層 <div class="tab_inner_wrap">...底下的tab內容都隱藏
document.getElementById(tablink).parentNode.querySelectorAll(".tab-inner").forEach(function (item) {
item.style.display = "none";
});
//因為剛剛是做全部底下的tab內容都隱藏,所以要再將剛剛抓出來的,例如是"two" tab內容秀出來
document.getElementById(tablink).style.display = "block";
});
});
附上JS切換程式碼
那...我們加碼分享Vue3版本
最近剛好要練Vue,請看我超新手寫法XD
引入
<script src="https://unpkg.com/vue@next"></script>
HTML
- 動態綁定classname 所以寫成:class 如果tabID是one的話就會有active這個class出現
- li 發生click事件時 所以寫成@click 並將id當參數傳進去 去改變tabID
<div id="app">
<div class="tab-demo">
<!-- tab標籤列 -->
<ul class="tab-title">
<li :class="{ 'active': tabID == 'one'}" @click="changeTab('one')">
<a href="javascript:;" data-tablink="one">tab1</a>
</li>
<li :class="{ 'active': tabID == 'two'}" @click="changeTab('two')">
<a href="javascript:;" data-tablink="two">tab2</a>
</li>
<li :class="{ 'active': tabID == 'three'}" @click="changeTab('three')">
<a href="javascript:;" data-tablink="three">tab3</a>
</li>
</ul>
<!-- tab內容 -->
<div class="tab-inner-wrap">
<div id="one" class="tab-inner" v-if="tabID == 'one'">
<!-- tab1的內容 -->
內容1 內容1 內容1 內容1
</div>
<div id="two" class="tab-inner" v-if="tabID == 'two'">
<!-- tab2的內容 -->
內容2
</div>
<div id="three" class="tab-inner" v-if="tabID == 'three'">
<!-- tab3的內容 -->
內容3
</div>
</div>
</div>
</div>
CSS同上喔
程式
const app = Vue.createApp({
data(){
return{
tabID:'one',
}
},
methods:{
changeTab(id){
this.tabID = id;
}
}
}).mount('#app')
附上程式碼
本篇參考文章:
https://www.webdesigns.com.tw/jquery_tab.asp