<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        li {
            list-style-type: none;
        }

        .tab {
            width: 978px;
            margin: 100px auto;
        }

        .tab_list {
            height: 39px;
            border: 1px solid #ccc;
            background-color: #f1f1f1;
        }

        .tab_list li {
            float: left;
            height: 39px;
            line-height: 39px;
            padding: 0 20px;
            text-align: center;
            cursor: pointer;
        }

        .tab_list .current {
            background-color: #c81623;
            color: #fff;
        }

        .item_info {
            padding: 20px 0 0 20px;
        }

        .item {
            display: none;
        }
    </style>
</head>

<body>
    <div class="tab">
        <div class="tab_list">
            <ul>
                <li class="tab-item current">首页</li>
                <li class="tab-item">新闻</li>
                <li class="tab-item">地址</li>
                <li class="tab-item">联系</li>
                <li class="tab-item">加入我们</li>
            </ul>
        </div>
        <div class="tab_con">
            <div class="item" style="display: block;">
                首页内容
            </div>
            <div class="item">
                XX凡进入了监狱,号称签签
            </div>
            <div class="item">
                我们在北京xxx监狱去探望
            </div>
            <div class="item">
                联系电话19089897867
            </div>
            <div class="item">
                快来加入我们一起行动吧
            </div>

        </div>
    </div>
    <script>

        // 点击tab按钮,展示相应模块信息
        // 事件源:tab按钮 (li)
        // 事件: onclick
        // 处理程序

        // 第一步 获取事件源
        var lis = document.getElementsByClassName('tab-item');
        var itemArr = document.getElementsByClassName('item');
        // 第二步绑定事件
        for (var i = 0; i < lis.length; i++) {
            lis[i].index = i;
            // 给每一个 li 追加 index 属性 ,保存自己的位置信息
            lis[i].onclick = function(){
                // 第三步:书写程序
                // 首先 点谁,谁高亮
                // 排他思想
                for(var j =0;j<lis.length;j++){
                    lis[j].classList.remove('current');
                }
                this.classList.add('current');
                // 其次展示相应的 模块
                // 思路:获取当前点击的 tab 的 位置(索引),然后从 itemArr里边找到同位置的模块

                // 如何获取当前点击的 tab 的索引(位置)
                // 这里边 慎用i 
                // console.log(i); // 永远是5

                // 我们可以通过 this  拿到点击元素(但是点击的元素并没有索引(位置)信息)
                // 我们可以提前处理 (将位置信息加到this身上即可)
                console.log(this.index);
                for(var j =0;j<itemArr.length;j++){
                    itemArr[j].style.display = 'none'
                }
                itemArr[this.index].style.display = 'block';
            }

            // 循环时,仅仅是绑定了 事件(函数),但是这个函数 并没有执行
            // 当点击触发 函数时,for循环早已结束,此时i的值 已经变为了5
        }

    </script>
</body>

</html>

为什么在for循环绑定事件时,慎用i?

其实,我们一定要搞清楚,代码的编写和执行是分开的。换言之,事件的执行一定是分两个过程:

  • 注册过程,绑定过程。(for循环只是在完成该过程)
  • 触发了,执行注册好代码。(此时运行绑定函数中的代码)

当事件触发时,for循环早已经结束,此时函数中的i已经变为了循环结束时的值。

解决办法:

循环绑定事件时,给每一个li元素人为添加一个属性,存储该li的索引信息,需要时直接取出。

文档更新时间: 2022-02-11 09:24   作者:张老师