将onclick事件添加到表格行

42

我正在尝试通过Javascript向表格行添加onclick事件。

function addRowHandlers() {
    var table = document.getElementById("tableId");
    var rows = table.getElementsByTagName("tr");
    for (i = 1; i < rows.length; i++) {
        row = table.rows[i];
        row.onclick = function(){
                          var cell = this.getElementsByTagName("td")[0];
                          var id = cell.innerHTML;
                          alert("id:" + id);
                      };
    }
}

在Firefox中,这个代码可以正常工作,但在Internet Explorer(IE8)中,我无法访问表格单元格。我认为这与onclick函数中的"this"被识别为"Window"而不是"Table"(或类似的东西)有关。

如果我能够访问当前行,我就可以在onclick函数中执行getElementById,但我找不到方法来实现这一点。有什么建议吗?


1
你应该从索引0开始(var i = 0;),而不是1。 - SolutionYogi
12个回答

56

就像这样。

function addRowHandlers() {
  var table = document.getElementById("tableId");
  var rows = table.getElementsByTagName("tr");
  for (i = 0; i < rows.length; i++) {
    var currentRow = table.rows[i];
    var createClickHandler = function(row) {
      return function() {
        var cell = row.getElementsByTagName("td")[0];
        var id = cell.innerHTML;
        alert("id:" + id);
      };
    };
    currentRow.onclick = createClickHandler(currentRow);
  }
}

编辑

以下是可工作的演示链接。


你确定吗?它是有效的。请在我的更新答案中检查工作演示链接。此外,在您的代码中,您从1开始索引而不是0。这样您将无法将处理程序附加到第一行。 - SolutionYogi
它能工作,但当我看到你的解决方案时,它与现在有点不同... =P 我非常感激,整个下午都在苦思冥想! - user80978
是的,我发完回答后就意识到了这一点(就像redsquare一样),然后进行了更正。 - SolutionYogi
为什么需要table.rows[i]?我尝试了“var currentRow = rows[i]”也可以。 - vaichidrewar
@CromeX,你能否给我们提供你所拥有的关于错误信息的代码片段: WHte.js:3 Uncaught TypeError: Cannot read property 'getElementsByTagName' of null。 如果你能告诉我们你正在构建的网页以及在网页浏览器上期望的结果,那就太好了。请发送页面截图,这样我们可以想象如何帮助你动态加载这三行。如果你已经解决了问题或者仍在尝试如何规避它,请告诉我们。 - Caleb Yang
显示剩余3条评论

11

生成代码的简单方法如下:

<!DOCTYPE html>
<html>
<head>

<style>
  table, td {
      border:1px solid black;
  }
</style>

</head>
<body>
<p>Click on each tr element to alert its index position in the table:</p>
<table>
  <tr onclick="myFunction(this)">
    <td>Click to show rowIndex</td>
  </tr>
  <tr onclick="myFunction(this)">
    <td>Click to show rowIndex</td>
  </tr>
  <tr onclick="myFunction(this)">
    <td>Click to show rowIndex</td>
  </tr>
</table>

<script>
  function myFunction(x) {
      alert("Row index is: " + x.rowIndex);
  }
</script>

</body>
</html>


8

我认为对于IE浏览器,你需要使用事件对象的srcElement属性。如果您可以使用jQuery,建议您考虑使用它,因为它可以为您抽象出大多数浏览器差异。以下是一个jQuery示例:

$("#tableId tr").click(function() {
   alert($(this).children("td").html());
});

4
这是与上述@redsquare和@SolutionYogi讨论的内容相同,但更加简洁干净的纯Javascript(不是jQuery)解决方案的版本。它可以在所有主要的Web浏览器中使用,包括最新的IE11。
function addRowHandlers() {
    var rows = document.getElementById("tableId").rows;
    for (i = 0; i < rows.length; i++) {
        rows[i].onclick = function(){ return function(){
               var id = this.cells[0].innerHTML;
               alert("id:" + id);
        };}(rows[i]);
    }
}
window.onload = addRowHandlers();

工作中演示

注意:为了使其在IE8中也能正常工作,建议使用显式标识符function(myrow)代替this指针。祝好!


1
我是如何做到这一点的。我创建了一个带有thead和tbody标签的表格。然后通过id向tbody元素添加了点击事件。
<script>
    document.getElementById("mytbody").click = clickfunc;
    function clickfunc(e) {
        // to find what td element has the data you are looking for
        var tdele = e.target.parentNode.children[x].innerHTML;
        // to find the row
        var trele = e.target.parentNode;
    }
</script>
<table>
    <thead>
        <tr>
            <th>Header 1</th>
            <th>Header 2</th>
        </tr>
    </thead>
    <tbody id="mytbody">
        <tr><td>Data Row</td><td>1</td></tr>
        <tr><td>Data Row</td><td>2</td></tr>
        <tr><td>Data Row</td><td>3</td></tr>
    </tbody>
</table>

1

沉迷于 jq 太久了,这个会起作用。

function addRowHandlers() {
    var table = document.getElementById("tableId");
    var rows = table.getElementsByTagName("tr");
    for (i = 1; i < rows.length; i++) {
        var row = table.rows[i];
        row.onclick = function(myrow){
                          return function() { 
                             var cell = myrow.getElementsByTagName("td")[0];
                             var id = cell.innerHTML;
                             alert("id:" + id);
                      };
                  }(row);
    }
}

这样行吗?我发布了相同的示例,但我认为在onclick内部的“row”始终会引用最后一行。是吗?[JavaScript仅具有函数作用域,没有块作用域。] - SolutionYogi
我知道,有了jQuery所有这些事情都变得很容易,但是当你没有jQuery时,你会犯一些愚蠢的错误! :) - SolutionYogi
确实如此!给我一个每天。 - redsquare

1
我试图通过纯JS获得更好的结果,最终得到了这个代码:

演示: https://jsfiddle.net/f5r3emjt/1/

const tbody = document.getElementById("tbody");
let rowSelected;

tbody.onclick = (e) => {
  for (let i = 0; i < e.path.length; ++i) {
    if (e.path[i].tagName == "TR") {
      selectRow(e.path[i]);
      break;
    }
  }
};

function selectRow(r) {
  if (rowSelected !== undefined) rowSelected.style.backgroundColor = "white";

  rowSelected = r;
  rowSelected.style.backgroundColor = "dodgerblue";
}

现在,您可以像您想要的那样在其他函数中使用变量 rowSelected,或者在设置样式后调用另一个函数。 我更喜欢这种实现方式,并且与任何浏览器兼容。
tbody.onclick = (e) => {
 // we need to get the tr element because we always select the td element
 const tr = e.srcElement.parentNode; 
 tr == "TR" && selectRow( tr );
};

0

我试图选择一个表格行,以便可以轻松地将其复制到剪贴板中,然后粘贴到Excel中。以下是您解决方案的小改编。

参考资料:

<!DOCTYPE html>
<html>
<body>

<div>
    <table id="tableId" border=1>
      <tbody>
        <tr><td>Item <b>A1</b></td><td>Item <b>B1</b></td></tr>
        <tr><td>Item <b>A2</b></td><td>Item <b>B2</b></td></tr>
        <tr><td>Item <b>A3</b></td><td>Item <b>B3</b></td></tr>
      </tbody>
    </table>
</div>

<script>
function addRowHandlers() {
    var table = document.getElementById("tableId");
    var rows = table.getElementsByTagName("tr");
    for (i = 0; i < rows.length; i++) {
        var currentRow = table.rows[i];
        var createClickHandler = 
            function(row) 
            {
                return function() { 
                                        var cell = row.getElementsByTagName("td")[0];
                                        var id = cell.innerHTML;

                                        var cell1 = row.getElementsByTagName("td")[1];
                                        var id2 = cell1.innerHTML;
                                        // alert(id + " - " + id2);
                                        window.prompt("Copy to clipboard: Ctrl+C, Enter", "<table><tr><td>" + id + "</td><td>" + id2 + "</td></tr></table>")
                                 };
            };

        currentRow.onclick = createClickHandler(currentRow);
    }
}
window.onload = addRowHandlers();
</script>
</body>
</html> 

0

虽然大多数答案都是SolutionYogi的复制,但它们都错过了一个重要的检查,即检查“cell”是否为null,这将在单击标题时返回错误。因此,以下是包含检查的答案:

function addRowHandlers() {
  var table = document.getElementById("tableId");
  var rows = table.getElementsByTagName("tr");
  for (i = 0; i < rows.length; i++) {
    var currentRow = table.rows[i];
    var createClickHandler = function(row) {
      return function() {
        var cell = row.getElementsByTagName("td")[0];
        // check if not null
        if(!cell) return; // no errors! 
        var id = cell.innerHTML;
        alert("id:" + id);
      };
    };
    currentRow.onclick = createClickHandler(currentRow);
  }
}

0

尝试将this.getElementsByTagName("td")[0])行更改为row.getElementsByTagName("td")[0];。这应该会在闭包中捕获row引用,并且应该按预期工作。

编辑:上面的方法是错误的,因为row是全局变量 - 正如其他人所说,分配一个新变量,然后在闭包中使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接