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

循环动态添加div绑定点击事件为何仅打印最后一个元素ID?

问题原因与解决方案

核心原因

你遇到的问题是因为**innerHTML +=的渲染机制导致之前绑定的事件全部丢失**:

每次执行wrapper.innerHTML += ...时,浏览器会把wrapper当前的所有子元素转成HTML字符串,拼接新内容后重新解析成DOM元素替换原内容。这意味着之前添加的div会被重新创建,之前绑定的点击事件会直接失效。只有最后一次循环中给最后一个div绑定的事件会保留,所以点击前面的div没反应,只有点击最后一个会打印它的id。

另外,用document.querySelector每次查询DOM也会额外消耗性能,不是最优的做法。


修复方案

方案1:用createElement创建元素(推荐)

这种方式不会重新渲染已有元素,事件绑定不会丢失:

let arr = ['a', 'b', 'c']
const wrapper = document.querySelector('.wrapper')

for (var i = 0; i < arr.length; i++) {
  const container = document.createElement('div')
  container.className = 'container'
  container.id = arr[i]
  
  container.onclick = (e) => {
    console.log(e.target.id)
  }
  
  wrapper.appendChild(container)
}

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

不需要给每个div单独绑定事件,利用事件冒泡把事件绑定到父元素上:

let arr = ['a', 'b', 'c']
const wrapper = document.querySelector('.wrapper')

// 一次性添加所有元素
arr.forEach(item => {
  wrapper.innerHTML += `<div class="container" id="${item}"></div>`
})

// 父元素统一处理点击事件
wrapper.onclick = (e) => {
  if (e.target.classList.contains('container')) {
    console.log(e.target.id)
  }
}

这种方式适合大量元素的场景,减少事件绑定次数,性能更优。

方案3:添加完所有元素后统一绑定事件

如果坚持要用innerHTML +=,可以先把所有元素添加完成,再批量绑定事件:

let arr = ['a', 'b', 'c']
const wrapper = document.querySelector('.wrapper')

// 先添加所有div
for (var i = 0; i < arr.length; i++) {
  wrapper.innerHTML += `<div class="container" id="${arr[i]}"></div>`
}

// 给所有container绑定事件
document.querySelectorAll('.container').forEach(container => {
  container.onclick = (e) => {
    console.log(e.target.id)
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:23:16