无法使用按钮从动态生成的 table 中正确删除行

Can't properly delete rows from a dynamically generated table using a button

我有以下代码,它应该在 table 中生成行,其中每一行都有自己的内容和删除按钮。

<!DOCTYPE html>
<html>
    <head>
        <title>table</title>
    </head>
    <body>
        <input id="inputText">
        <button onclick = "addRow()">Add text</button>

        <table id = "table">
        </table>
        <script>
            function addRow(){

                var newRow = document.createElement("tr");
                var col1 = document.createElement("td");
                var col2 = document.createElement("td");
                newRow.appendChild(col1);
                newRow.appendChild(col2);

                var button = document.createElement("button");
                button.innerHTML = "delete";

                button.onclick = function () {
                    var index = this.parentNode.parentNode.rowIndex;
                    document.getElementById("table").deleteRow(index);
                }
                col1.appendChild(button);


                var enteredText = document.getElementById("inputText").value;
                col2.innerHTML = enteredText;

                document.getElementById("table").appendChild(newRow);

            }
        </script>
    </body>
</html>

问题是无论我按哪个删除按钮,它都会删除最后一行。 我尝试使用 console.log(this.parentNode.parentNode) 来查看它 returns 是否是正确的 <tr> 对象,它确实如此。但是由于某种原因,无论按下什么按钮,属性 rowIndex 都是-1;因此只有最后一行被删除。这是否意味着每个动态生成的 <tr> 不知道其行索引?

您可以改用 HTMLTableElement.insertRow() 函数。

var newRow = document.getElementById("table").insertRow();
// newRow.rowIndex will return you the proper index

Here is a working fiddle

更新

这是 Webkit 布局引擎中的一个错误(也转移到了分叉的 Blink 引擎)。这就是为什么它在 Firefox 中运行良好但在 Chrome (Blink) 或 Safari (Webkit) 的 早期版本中运行不佳的原因。

错误报告 here,现已修复。

有多种方法可以实现您的要求。这是另一个基于您发布的代码的示例。希望它能给你一些进一步的想法。

(function() {
  // create references to static elements, no need to search for them each time
  var inputText = document.getElementById("inputText"),
      butAdd = document.getElementById("butAdd"),
      table = document.getElementById("table");

  // a generic function for finding the first parent node, starting at the given node and
  // of a given tag type. Retuns document if not found.
  function findParent(startNode, tagName) {
    var currentNode,
        searchTag;

    // check we were provided with a node otherwise set the return to document
    if (startNode && startNode.nodeType) {
      currentNode = startNode;
    } else {
      currentNode = document;
    }

    // check we were provided with a string to compare against the tagName of the nodes
    if (typeof tagName === 'string') {
      searchTag = tagName.toLowerCase();
    } else {
      currentNode = document;
    }

    // Keep searching until we find a parent with a mathing tagName or until we get to document
    while (currentNode !== document && currentNode.tagName.toLowerCase() !== searchTag) {
      currentNode = currentNode.parentNode;
    }

    // return the match or document
    return currentNode;
  }

  // for deleting the current row in which delete was clicked
  function deleteRow(e) {
    // find the parent with the matching tagName
    var parentTr = findParent(e.target, 'tr');

    // did we find it?
    if (parentTr !== document) {
      // remove it
      parentTr.parentNode.removeChild(parentTr);
    }
  }

  // for adding a row to the end of the table
  function addRow() {
    // create the required elements
    var newRow = document.createElement("tr"),
        col1 = document.createElement("td"),
        col2 = document.createElement("td"),
        button = document.createElement("button");

    // add some text to the new button
    button.appendChild(document.createTextNode("delete"));
    // add a click event listener to the delete button
    button.addEventListener('click', deleteRow, false);

    // append all the required elements
    col1.appendChild(button);
    col2.appendChild(document.createTextNode(inputText.value));
    newRow.appendChild(col1);
    newRow.appendChild(col2);

    // finally append all the elements to the document
    table.appendChild(newRow);
  }

  // add click event listener to the static Add text button
  butAdd.addEventListener('click', addRow, false);
}());
<input id="inputText">
<button id="butAdd">Add text</button>
<table id="table"></table>