1. 程式人生 > >js之選項卡

js之選項卡

接觸js也有幾天了,今天研究了一下選項卡的編寫,中間磕磕絆絆,好多疑問,不過經過百度等各渠道查詢,解決了遇到的問題,也做出了想要的效果。下面我放上自己的程式碼,也說一下遇到的困惑以及解決的辦法。
選項卡需求:

  1. 點選按鈕背景色變色,其餘按鈕背景色回覆預設樣式;
  2. 點選按鈕時,讓下方盒子內容聯動。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="keywords" content="">
    <meta name="description" content="">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>Title</title>
    <link rel="icon" href="">
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        .tab {
            position: relative;
            bottom: -1px;
            overflow: hidden;
        }
        .tab li {
            float: left;
            width: 100px;
            height: 50px;
            line-height: 50px;
            border: 1px solid #ccc;
            box-sizing: border-box;
            text-align: center;
        }
        .box {
            clear: both;
            width: 500px;
            height: 500px;

        }
        .box li {
            width: 100%;
            height: 100%;
            text-align: center;
            line-height: 500px;
            background: aquamarine;
            display: none;
        }
        .select {
            background: aquamarine;
            display: block !important;
        }
        .tab .select{
            border-bottom: none;
        }
    </style>
</head>
<body>
<ul class="tab">
    <li class="select">河南</li>
    <li>北京</li>
    <li>重慶</li>
    <li>天津</li>
    <li>山東</li>
</ul>
<ul class="box">
    <li class="select">燴麵</li>
    <li>烤鴨</li>
    <li>小面</li>
    <li>狗不理</li>
    <li>煎餅</li>
</ul>
<script>
    var oTab = document.getElementsByClassName("tab");
    var oTabLis = oTab[0].getElementsByTagName("li");
    var oBox = document.getElementsByClassName("box");
    var oBoxLis = oBox[0].getElementsByTagName("li");

    function change(index) {  //index:給函式傳入的一個形參,一個入口,實現方法的時候我們不知道使用者點選哪一個li,設定一個入口,當用戶點選需要頁卡切換的時候,只要執行change這個方法,並把點選這個li的索引傳遞給我們,我們就可以在集合中通過索引獲取當前點選的這個li物件
        for (var i = 0; i < oTabLis.length; i++) {
            oTabLis[i].className = ""; //讓所有的li移除select樣式類
            oBoxLis[i].className = "";
        }
       
        //讓當前點選的li有選中的樣式
        oTabLis[index].className = "select";
        oBoxLis[index].className = "select";
    }

     //給每一個li繫結點選事件,點選的時候執行change方法,把當前點選li的索引傳遞進來,實現頁卡的切換。
    for (var i = 0; i < oTabLis.length; i++) {
        oTabLis[i].myIndex = i; //這個是我遇到最困惑的地方,我在下邊詳細說一下。這標記為a處吧
        oTabLis[i].onclick = function () {
            change(this.myIndex);
        }
    }
</script>
</body>
</html>

這裡我說的都是a處的內容,也就是點選事件的部分。如果此處這樣寫:

  for (var i = 0; i < oTabLis.length; i++) {
      
        oTabLis[i].onclick = function () {
            change(i);
        }

乍一看,沒有問題,但是你會發現執行不出來,這是什麼情況呢?我們不妨控制檯輸出一下

 for (var i = 0; i < oTabLis.length; i++) {
      
        oTabLis[i].onclick = function () {
           // change(i);
              console.log(i);
        }

你會發現,不管點選哪一個li,輸出的結果都是5,也就是此處的i並不是想象中點選的這個li的索引。這就很明顯了,肯定是change(i)這裡出現了問題。那麼為什麼出現這樣的問題呢?
首先,我們要搞清楚,函式分為定義函式和執行函式,在這裡給元素點選事件繫結方法,點選才執行,此處繫結屬於建立函式,空間中儲存的都是字串:也就是說,這裡的i不是變數,而是字元。因此有了下面的輸出:

//第一輪
 oTabLis[0].onclick = function () {
              console.log(i);

//第二輪
 oTabLis[1].onclick = function () {
              console.log(i);
……
//第五輪
 oTabLis[5].onclick = function () {
              console.log(i);

//迴圈結束的時候,i=5

迴圈結束的時候,i的值是5。假設使用者開始點選第二個li,開始執行第二個繫結方法(方法執行:形成一個新的作用域,把之前空間中儲存的字串轉化為程式碼執行,console.log(i),但是此時輸出的是迴圈結束時的5)。
所以我們用自定義屬性,有了以下的程式碼:

   for (var i = 0; i < oTabLis.length; i++) {
        oTabLis[i].myIndex = i;//用來儲存每次迴圈i的值
        oTabLis[i].onclick = function () {
            change(this.myIndex);//此處需要傳遞當前點選這個li的索引
           //this:當前點選的這個li
           //this.myIndex:當前點選這個li的myIndex這個自定義屬性的值
        }
    }

i=0
 oTabLis[0].myIndex = 0;
i=1
 oTabLis[1].myIndex = 1;
i=2
 oTabLis[2].myIndex = 2;
i=3
 oTabLis[3].myIndex = 3;
i=4
 oTabLis[4].myIndex = 4;
//這裡相當於給每個li添加了一個便籤,方便取用。

以上就是我對選項卡的理解以及遇到的問題,如有表達錯誤的地方,請及時提出!