tab切換案例

最終效果如下:


tab切換案例

html布局如下:

<style type="text/css">
.tab{
    border:5px solid #999;
    width:500px;
    margin:0 auto;
    height:350px;
    overflow:hidden;
}
.tab ul,.tab ol{
    list-style:none;
    padding:0;
    margin:0;
}
.tab ul{
    display:flex;
    justify-content:space-evenly;
    background:pink;
}
.tab ul li{
    width:150px;
    height:50px;
    line-height:50px;
    font-size:30px;
    font-weight:bold;
    text-align:center;
    background:pink;
}
.tab ul li.active{
    background:#ff0;
}
.tab ol li{
    height:300px;
    text-align:center;
    display:none;
}
.tab ol li a img{
    width: 500px;
    height: 300px;
}
.tab ol li.active{
    display:block;
}
.tab:hover{
    cursor: pointer;
}
</style>
<div class="tab">
    <ul>
        <li class="active">小豬</li>
        <li>小狗</li>
        <li>猩猩</li>
    </ul>
    <ol>
        <li class="active">
            <a href="">
                <img src="./img/1.jpg" alt="">
            </a>
        </li>
        <li>
            <a href="">
                <img src="./img/2.jpg" alt="">
            </a>
        </li>
        <li>
            <a href="">
                <img src="./img/3.jpg" alt="">
            </a>
        </li>
    </ol>
</div>

js實(shí)現(xiàn)代碼:

// 獲取所有標(biāo)簽
var oUlis = document.querySelectorAll('.tab ul li');
var oOlis = document.querySelectorAll('.tab ol li');

具體切換的js代碼寫法有多種
方法一:提前給所有li添加屬性(顯示在標(biāo)簽上的屬性),值為下標(biāo)

// 遍歷ul中所有l(wèi)i
for(var i=0;i<oUlis.length;i++){
    // 給所有ul下的li添加屬性,值為他們?cè)趗l中的下標(biāo)
    oUlis[i].setAttribute('index',i)
    // 給ul下所有l(wèi)i綁定單擊事件
    oUlis[i].onclick = function(){
        // 將所有l(wèi)i標(biāo)簽的類名清空
        for(var j=0;j<oUlis.length;j++){
            oUlis[j].className = ''
            oOlis[j].className = ''
        }
        // 給當(dāng)前點(diǎn)擊的ul下的li添加active類名
        this.className = 'active';
        // 找到當(dāng)前l(fā)i在ul中的下標(biāo)
        var index = this.getAttribute('index')
        // 根據(jù)當(dāng)前l(fā)i的下標(biāo)找到對(duì)應(yīng)的ol下應(yīng)該顯示的li,給他添加active類名
        oOlis[index].className = 'active';
    }
}

方法二:提前給所有li添加屬性(不顯示在標(biāo)簽上的屬性),值為下標(biāo)

for(var i=0;i<oUlis.length;i++){
    // 給所有ul下的li添加屬性,值為他們?cè)趗l中的下標(biāo)
    oUlis[i].index = i
    // 給ul下所有l(wèi)i綁定單擊事件
    oUlis[i].onclick = function(){
        // 將所有l(wèi)i標(biāo)簽的類名清空
        for(var j=0;j<oUlis.length;j++){
            oUlis[j].className = ''
            oOlis[j].className = ''
        }
        // 給當(dāng)前點(diǎn)擊的ul下的li添加active類名
        this.className = 'active';
        // 找到當(dāng)前l(fā)i在ul中的下標(biāo)
        var index = this.index
        // 根據(jù)當(dāng)前l(fā)i的下標(biāo)找到對(duì)應(yīng)的ol下應(yīng)該顯示的li,給他添加active類名
        oOlis[index].className = 'active';
    }
}

方法三:在事件外嵌套一個(gè)自調(diào)用函數(shù),將遍歷的下標(biāo)當(dāng)做參數(shù)傳入

for(var i=0;i<oUlis.length;i++){
    (function(i){
        // 給ul下所有l(wèi)i綁定單擊事件
        oUlis[i].onclick = function(){
            // 將所有l(wèi)i標(biāo)簽的類名清空
            for(var j=0;j<oUlis.length;j++){
                oUlis[j].className = ''
                oOlis[j].className = ''
            }
            // 給當(dāng)前點(diǎn)擊的ul下的li添加active類名
            this.className = 'active';
            // 根據(jù)當(dāng)前l(fā)i的下標(biāo)找到對(duì)應(yīng)的ol下應(yīng)該顯示的li,給他添加active類名
            oOlis[i].className = 'active';
        }   
    })(i)
}

方法四:將循環(huán)的i使用es6提供的let關(guān)鍵字來定義

for(let i=0;i<oUlis.length;i++){
    // 給ul下所有l(wèi)i綁定單擊事件
    oUlis[i].onclick = function(){
        // 將所有l(wèi)i標(biāo)簽的類名清空
        for(var j=0;j<oUlis.length;j++){
            oUlis[j].className = ''
            oOlis[j].className = ''
        }
        // 給當(dāng)前點(diǎn)擊的ul下的li添加active類名
        this.className = 'active';
        // 根據(jù)當(dāng)前l(fā)i的下標(biāo)找到對(duì)應(yīng)的ol下應(yīng)該顯示的li,給他添加active類名
        oOlis[i].className = 'active';
    }
}

方法五:在清除所有標(biāo)簽類名的時(shí)候,有2個(gè)標(biāo)簽本來就沒有類名,是無辜的,其實(shí)只需要清除帶有active類名的標(biāo)簽的類名即可

var uliActive = document.querySelector('.tab ul li.active');
var oliActive = document.querySelector('.tab ol li.active');
for(let i=0;i<oUlis.length;i++){
    // 給ul下所有l(wèi)i綁定單擊事件
    oUlis[i].onclick = function(){
        // 將帶有active類名的li標(biāo)簽的類名清空
        uliActive.className = '';
        oliActive.className = '';
        // 給當(dāng)前點(diǎn)擊的ul下的li添加active類名
        this.className = 'active';
        // 根據(jù)當(dāng)前l(fā)i的下標(biāo)找到對(duì)應(yīng)的ol下應(yīng)該顯示的li,給他添加active類名
        oOlis[i].className = 'active';
        // 將此時(shí)帶有active類名的標(biāo)簽賦值給上面的變量,以便下次清除時(shí)使用
        uliActive = this;
        oliActive = oOlis[i];
    }
}

總結(jié):上述幾種方法為什么要糾結(jié)當(dāng)前點(diǎn)擊的li的下標(biāo)呢?因?yàn)檠h(huán)中綁定事件,當(dāng)事件觸發(fā)的時(shí)候,循環(huán)的變量已經(jīng)是循環(huán)結(jié)束的變量值了。
頁面打開或刷新的時(shí)候,循環(huán)已經(jīng)運(yùn)行結(jié)束了,然后才觸發(fā)的事件,事件中使用的循環(huán)的變量,在事件函數(shù)的作用域中并沒有定義,所以會(huì)從上一層作用域(全局)中找這個(gè)變量的定義,全局中的循環(huán)已經(jīng)運(yùn)行結(jié)束了,所以循環(huán)的變量,無論點(diǎn)擊哪一個(gè)標(biāo)簽,循環(huán)的變量已經(jīng)是循環(huán)結(jié)束的值了。
所以,這多種方法,其實(shí)都是在通過各種方式來得到當(dāng)前點(diǎn)擊的這個(gè)li標(biāo)簽在ul中的下標(biāo)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容