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

如何解决jQuery定时创建DOM元素时的索引值错误问题?

修复setTimeout循环中索引值传递错误的方案

嘿,这个问题我太熟了!这是典型的闭包作用域陷阱——当你在for循环里用setTimeout时,所有的回调函数共享同一个var i变量。等定时器触发的时候,循环早就执行完了,i已经变成5了,所以每个createEle拿到的都是最后这个值,导致所有div都显示5。

下面给你三种靠谱的修复方法,任选其一就行:

方法1:用立即执行函数(IIFE)创建独立作用域

通过IIFE把每次循环的i值“固定”在一个独立的作用域里,这样每个回调函数绑定的都是当前迭代的数值:

$(document).ready(function() {
  for (var i = 0; i < 5; i++) {
    // 立即执行函数,把当前i作为参数传入
    (function(currentIndex) {
      setTimeout(function() {
        createEle(currentIndex);
      }, i * 1000);
    })(i);
  }
});

function createEle(value) {
  var d = $("<div></div>");
  d.addClass("d");
  d.html(value);
  $("#container").append(d);
}

方法2:用ES6的let声明变量

let在for循环里会为每一次迭代创建一个全新的变量绑定,天然避免了闭包陷阱,代码最简洁:

$(document).ready(function() {
  // 把var换成let,每个迭代的i都是独立的
  for (let i = 0; i < 5; i++) {
    setTimeout(function() {
      createEle(i);
    }, i * 1000);
  }
});

function createEle(value) {
  var d = $("<div></div>");
  d.addClass("d");
  d.html(value);
  $("#container").append(d);
}

方法3:利用setTimeout的第三个参数

现代浏览器支持给setTimeout传递额外参数,这些参数会直接作为回调函数的入参,不用依赖闭包:

$(document).ready(function() {
  for (var i = 0; i < 5; i++) {
    // 第三个参数i会传给回调函数的currentIndex
    setTimeout(function(currentIndex) {
      createEle(currentIndex);
    }, i * 1000, i);
  }
});

function createEle(value) {
  var d = $("<div></div>");
  d.addClass("d");
  d.html(value);
  $("#container").append(d);
}

配套的CSS和HTML代码保持不变:

.d {
  height: 20px;
  color: white;
  background: red;
  margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"> </div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:49:26