You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用onclick与querySelectorAll()修改两组div属性的绑定问题

问题分析

你遇到的是循环中闭包变量绑定的问题:用var声明的box1和box2没有块级作用域,循环结束后,这两个变量会保留最后一次循环的赋值(也就是最后一组的box1和box2),所以不管点击哪一组元素,触发的事件都会操作最后一组的DOM。

解决方案

下面提供几种可行的修复方式:

方案1:用let代替var(最简单)

把循环里的var改成let,let会创建块级作用域,每次循环都会生成新的变量绑定,确保每个点击事件都能拿到当前循环对应的box1和box2:

<script type='text/javascript'>
    var box1Temp = document.querySelectorAll(".box1");
    var box2Temp = document.querySelectorAll(".box2");
    for (let i = 0; i < box1Temp.length; i++) {
        let box1 = box1Temp[i];
        let box2 = box2Temp[i];
        box2.onclick = box1.onclick = function() {
            if (box1.classList.contains("colorGreen")) {
                box1.classList.add("colorRed");
                box1.classList.remove("colorGreen");
                box2.innerHTML = "Text2";
            } else {
                box1.classList.add("colorGreen");
                box1.classList.remove("colorRed");
                box2.innerHTML = "Text1";
            }
        }
    }
</script>

方案2:用闭包包裹(兼容旧浏览器)

如果要兼容不支持ES6的旧浏览器,可以用立即执行函数(IIFE)把每次循环的变量包裹起来,形成独立作用域:

<script type='text/javascript'>
    var box1Temp = document.querySelectorAll(".box1");
    var box2Temp = document.querySelectorAll(".box2");
    for (var i = 0; i < box1Temp.length; i++) {
        (function(box1, box2) {
            box2.onclick = box1.onclick = function() {
                if (box1.classList.contains("colorGreen")) {
                    box1.classList.add("colorRed");
                    box1.classList.remove("colorGreen");
                    box2.innerHTML = "Text2";
                } else {
                    box1.classList.add("colorGreen");
                    box1.classList.remove("colorRed");
                    box2.innerHTML = "Text1";
                }
            }
        })(box1Temp[i], box2Temp[i]);
    }
</script>

方案3:用data-*属性关联对应元素(更灵活)

给每个box1和box2添加对应的索引,点击时通过索引找到配对的元素,不需要依赖循环变量:

修改后的HTML

<style>
    .colorGreen {
        background-color: green;
    }

    .colorRed {
        background-color: red;
    }
</style>

<div class="box2" data-index="0">Text1</div>
<div class="box1 colorGreen" data-index="0">O</div>
<div class="box2" data-index="1">Text1</div>
<div class="box1 colorGreen" data-index="1">O</div>
<div class="box2" data-index="2">Text1</div>
<div class="box1 colorGreen" data-index="2">O</div>

修改后的JavaScript

<script type='text/javascript'>
    var box1List = document.querySelectorAll(".box1");
    var box2List = document.querySelectorAll(".box2");
    
    function toggleElements(index) {
        var box1 = box1List[index];
        var box2 = box2List[index];
        if (box1.classList.contains("colorGreen")) {
            box1.classList.add("colorRed");
            box1.classList.remove("colorGreen");
            box2.innerHTML = "Text2";
        } else {
            box1.classList.add("colorGreen");
            box1.classList.remove("colorRed");
            box2.innerHTML = "Text1";
        }
    }

    // 给所有box2绑定点击事件
    box2List.forEach(function(box, index) {
        box.onclick = function() {
            toggleElements(index);
        }
    });

    // 给所有box1绑定点击事件
    box1List.forEach(function(box, index) {
        box.onclick = function() {
            toggleElements(index);
        }
    });
</script>

方案4:事件委托(更高效)

如果元素数量很多,推荐用事件委托,只给父元素绑定一次事件,通过事件冒泡判断点击的元素:

先给元素加父容器

<div class="container">
    <div class="box2">Text1</div>
    <div class="box1 colorGreen">O</div>
    <div class="box2">Text1</div>
    <div class="box1 colorGreen">O</div>
    <div class="box2">Text1</div>
    <div class="box1 colorGreen">O</div>
</div>

JavaScript代码

<script type='text/javascript'>
    var container = document.querySelector(".container");
    var box1List = document.querySelectorAll(".box1");
    var box2List = document.querySelectorAll(".box2");

    container.onclick = function(e) {
        var target = e.target;
        // 点击的是box2
        if (target.classList.contains("box2")) {
            var index = Array.from(box2List).indexOf(target);
            var box1 = box1List[index];
            toggle(box1, target);
        } 
        // 点击的是box1
        else if (target.classList.contains("box1")) {
            var index = Array.from(box1List).indexOf(target);
            var box2 = box2List[index];
            toggle(target, box2);
        }
    }

    function toggle(box1, box2) {
        if (box1.classList.contains("colorGreen")) {
            box1.classList.add("colorRed");
            box1.classList.remove("colorGreen");
            box2.innerHTML = "Text2";
        } else {
            box1.classList.add("colorGreen");
            box1.classList.remove("colorRed");
            box2.innerHTML = "Text1";
        }
    }
</script>

内容的提问来源于stack exchange,提问作者Thornan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:51:16