【问题标题】:How to add event listener to each cell in a table?如何为表格中的每个单元格添加事件侦听器?
【发布时间】:2018-09-30 18:57:09
【问题描述】:

假设我有一个如下所示的网格(单元格内的数字仅用于标记,它可能只是空单元格):

用HTML写成如下:

<table>
      <tr>
        <td>0 </td>
        <td>1 </td>
      </tr>
      <tr>
        <td>2 </td>
        <td>3 </td>
      </tr>
</table>

我想做两件事:

  1. 添加一些 JavaScript 代码,在单击每个单元格时将单元格的编号记录到控制台。我是这样做的:
const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener('click', function () {
    console.log(i);
  });
}

但是无论我在哪里单击表格,控制台总是返回值 4。我的问题是:

  1. 通过在f​​or循环的每次迭代中添加cells[i].addEventListener,是否会为每个cell添加一个事件监听器?
  2. 为什么即使我点击了单元格[0]、单元格[\1]、单元格[2]或单元格[3],控制台总是返回4?
  3. 我应该怎么做才能使控制台返回数组单元格中的所需位置,即如果单击单元格 [0] 则返回 0,如果单击单元格 [\1] 则返回 1,如果单击单元格 [2] 则返回 2 ],如果我单击单元格[3],则返回 3?

接下来,

  1. 我想做的第二件事是根据我从 HTML 设置的颜色选择器中选择的颜色更改每个单元格的颜色:&lt;input type="color" id="colorPicker"&gt;

我是这样做的:

const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener('click', function () {    
    const color = document.querySelector('#colorPicker').value;
    cells[i].style.backgroundColor = color;
  });
}

但是单元格的颜色没有改变。

我不打算使用 jQuery,我只想使用基本的 JavaScript 来为每个单元格添加一个事件监听器。几个小时以来,我一直试图找出一些方法,但最终还是一无所知。有人可以帮忙吗?非常感谢,谢谢!

【问题讨论】:

  • 更多关于为什么添加到循环中的事件监听器都在记录4,以及修复它的各种方法,请参阅这个问题及其答案,以及几个相关的:@ 987654322@

标签: javascript html events dom addeventlistener


【解决方案1】:

因为 i 是递增的,所以在 for 循环完成后 i == cells.length。

代替...

for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener('click', function () {
    console.log(i);
  });
}

使用...

for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener('click', function (e) {
    console.log(e.target);
  });
}

你的后一个例子也是如此......

【讨论】:

    【解决方案2】:

    是因为您在回调中使用了“i”变量。并且“i”在循环结束时具有值:4,因此当您单击回调时,您的应用会使用最后一个值。

    只需通过以下方式更改您的代码:

    const cells = document.querySelectorAll('td');
    for (var i = 0; i < cells.length; i++) {
      console.log(cells[i].innerText);
      cells[i].addEventListener('click', (event) => {
        console.log(event.target.innerText); // Take the text node from the element who fire the click event.
    
        // If you don't want to use innerText, you can do like this.
            console.log(
               //We transform querySelectorAll to traversable array. Then we find index of current event target.
               Array.from(document.querySelectorAll('td')).findIndex(e => e === event.target)
            );
    
      });
    }
    

    第二个案例基于 colorPicker :

    const cells = document.querySelectorAll('td');
    for (var i = 0; i < cells.length; i++) {
      cells[i].addEventListener('click', function (event) {    
        const color = document.querySelector('#colorPicker').value;
        event.target.style.backgroundColor = color;
      });
    }
    

    live sample

    【讨论】:

    • 非常感谢!对于第一种情况只有一个问题,如果单元格中没有文本怎么办?我们不能再使用 .innerText 了吧?那么如何打印数组的位置i呢?
    • 我已经用另一种查找索引的方法更新了我的答案;)希望这会对你有所帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多