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

如何在JavaScript动态生成的表格中获取td的innerHTML

解决动态生成表格点击单元格无法获取对应文本的问题

这个问题是典型的闭包作用域陷阱,我来帮你拆解原因和解决办法:

为什么原来的代码会出错?

你在循环里给每个td绑定onclick事件时,事件函数并没有立刻执行——它要等到你点击单元格才会触发。而循环结束后,变量td已经指向了最后一次循环创建的那个单元格,所以不管你点哪个单元格,check函数里的td都会指向最后一个单元格的内容。

三种可行的解决方案

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

把当前循环的td作为参数传入立即执行函数,让每个事件函数都能捕获到当前的td引用:

var myTableDiv = document.getElementById("results")
var table = document.createElement('TABLE')
var tableBody = document.createElement('TBODY')
table.border = '1'
table.appendChild(tableBody);

//TABLE ROWS
for (i = 0; i < this.memo.length; i++) {
  var tr = document.createElement('TR');
  for (j = 0; j < this.memo[i].length; j++) {
    var td = document.createElement('TD');
    // 用IIFE保存当前td的引用
    td.onclick = (function(currentTd) {
      return function() {
        check(currentTd);
      };
    })(td);
    td.appendChild(document.createTextNode(this.memo[i][j]));
    tr.appendChild(td)
  }
  tableBody.appendChild(tr);
}
myTableDiv.appendChild(table);

// 修改check函数,接收当前元素作为参数
function check(element) {
  var a = element.innerHTML;
  console.log(a);
}

方案2:用ES6的let声明变量(最简单)

let会创建块级作用域,每次循环都会生成一个新的td变量,这样每个事件函数绑定的都是当前循环的td:

var myTableDiv = document.getElementById("results")
var table = document.createElement('TABLE')
var tableBody = document.createElement('TBODY')
table.border = '1'
table.appendChild(tableBody);

// 外层循环的i也可以用let,避免其他潜在问题
for (let i = 0; i < this.memo.length; i++) {
  var tr = document.createElement('TR');
  // 内层循环用let声明j,确保每次循环的作用域独立
  for (let j = 0; j < this.memo[i].length; j++) {
    let td = document.createElement('TD'); // 用let声明td
    td.onclick = function () { check(td); }
    td.appendChild(document.createTextNode(this.memo[i][j]));
    tr.appendChild(td)
  }
  tableBody.appendChild(tr);
}
myTableDiv.appendChild(table);

function check(element) {
  var a = element.innerHTML;
  console.log(a);
}

方案3:利用元素的自定义属性(最直观)

把要获取的文本直接存在td的自定义data-*属性里,点击时通过this(指向被点击的单元格)获取:

var myTableDiv = document.getElementById("results")
var table = document.createElement('TABLE')
var tableBody = document.createElement('TBODY')
table.border = '1'
table.appendChild(tableBody);

for (i = 0; i < this.memo.length; i++) {
  var tr = document.createElement('TR');
  for (j = 0; j < this.memo[i].length; j++) {
    var td = document.createElement('TD');
    // 把单词存在自定义data属性里
    td.dataset.word = this.memo[i][j];
    td.onclick = function () {
      // this指向被点击的td,直接取属性值
      console.log(this.dataset.word);
    }
    td.appendChild(document.createTextNode(this.memo[i][j]));
    tr.appendChild(td)
  }
  tableBody.appendChild(tr);
}
myTableDiv.appendChild(table);

这种方法不需要单独的check函数,逻辑更直接。

总结

推荐用方案2(let)或者方案3(自定义属性),代码更简洁易懂。核心思路就是让每个点击事件都能绑定到当前循环的单元格引用,而不是最后一个。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:34:42