无法理解为什么parentNode.removeChild不起作用

时间:2015-06-12 20:57:33

标签: javascript html

我是新手,我想了解一些东西。 好吧,这是我的HTML代码:

var counter = 0;

function addMore() {
  counter++;
  var newFields = document.getElementById('dupDiv').cloneNode(true);
  newFields.id = 'dupDiv' + counter;
  newFields.name = 'dupDiv' + counter;
  newFields.style.display = 'block';

  var insertHere = document.getElementById('writeroot');
  insertHere.parentNode.insertBefore(newFields, insertHere);
  document.getElementById('test').value = newFields.name;
}
window.onload = addMore();
<table id="mainTable" style="width: 700" align="center" dir="rtl">
  <tr>
    <td align="right" colspan="2">
      <form method="post" name="f1">
        <table align="right" width="600px">
          <tbody id="dupDiv" style="display:none;">
            <tr>
              <td class="a1"><input type="text" value="pp" /></td>
            </tr>
            <tr>
              <td class="a1">
                <input type="button" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" value="DELETE" />
              </td>
            </tr>
          </tbody>
          <span id="writeroot"></span>
          <tr>
            <td class="a1">
              <input type="button" onclick="addMore()" value="ADD MORE" />
            </td>
          </tr>
        </table>
      </form>
    </td>
  </tr>
</table>

正如您所看到的,代码正在运行,但它只删除按钮。 我希望它删除所有创建的tbody。 (我的意思是我想删除点击按钮的特定tbody)

如果有可能我想在我的代码中解释一下parentNode以及每次连接它的元素。

**这不是整个代码,因此可能缺少某些元素

1 个答案:

答案 0 :(得分:4)

您的点击处理程序似乎是这样的:

onclick="this.parentNode.parentNode.removeChild(this.parentNode);"

this将是点击的按钮。

this.parentNode将包含<td>

this.parentNode.parentNode将包含<tr>

因此,您正在获取包含行并告诉该行删除包含<td>的内容。这就是您的代码指示浏览器执行的操作。

如果您要尝试删除包含<tbody>元素的内容,则需要进一步升级层次结构以获取实际的<tbody>元素和{{1元素本身。

<table>

每当我看到需要使用多个var tbody = this.parentNode.parentNode.parentNode; tbody.parentNode.removeChild(tbody); 引用来达到这样的父层次结构时,代码看起来很脆弱(如果对HTML进行了轻微更改,它可能很容易破解)。例如,如果.parentNode标记仅仅包含在<input>中以便于格式化或布局,则会生成此代码。因此,我试图避免这种类型的代码。在这种情况下,您可以使用一个小实用程序函数来查找父类型父类型的父层次结构,然后即使对HTML进行了少量更改,它也会继续工作。这可能是我编写此代码的方式:

<div>

另外,改变:

// search up the parent chain for a particular tag type
function closestParentTag(start, tag) {
    var found;
    tag = tag.toLowerCase();
    while (start && start !== document.documentElement && !(found = start.tagName.toLowerCase() === tag)) {
        start = start.parentNode;
    }
    return found ? start : null;
}


function removeCurrentBody(elem) {
    var tbody = closestParentTag(elem, "tbody");
    if (tbody) {
        tbody.parentNode.removeChild(tbody);
    }
}

为:

window.onload = addMore();

你拥有它的方式是立即调用该函数。相反,您希望分配一个函数引用,以便可以将其命名为LATER。

在您的代码中,当您通过以下命名引用某个函数时,如下所示:

var foo = addMore;

即为变量window.onload = addMore; 分配函数引用。您可以将其视为指向函数foo的指针。现在什么都没有。您刚刚将指向该函数的指针指定给另一个变量。这是您传递或分配函数的方式,以便稍后由其他代理调用它们。

当你的代码中有一个函数名后面的parens时,该函数会立即执行。

addMore

立即执行 var foo = addMore(); 并将该函数的返回结果赋给变量addMore()