无法在节点上执行removeChild

时间:2017-03-22 15:59:28

标签: javascript

thisthis等其他堆叠答案似乎是特殊情况,我相信我的情况更为普遍。我在我的js中这样做:

var markerDiv = document.createElement("div");
markerDiv.innerHTML = "<div id='MyCoolDiv' style='color: #2b0808'>123</div>";
document.getElementById("playerContainer").appendChild(markerDiv);

// after a brief delay, REMOVE the appended child
setTimeout(function(){ 
    var myCoolDiv = document.getElementById("MyCoolDiv");
    document.getElementById("playerContainer").removeChild(myCoolDiv);
}, 1500);

在调用removeChild()之前,所有内容都正常工作并且符合预期(div已正确附加,我可以看到它),此时我收到错误Failed to execute 'removeChild' on 'Node'

我做错了什么?

6 个答案:

答案 0 :(得分:8)

您的myCoolDiv元素不是播放器容器的子级。它是您作为其包装器创建的div的子项(代码的第一部分中为markerDiv)。这就是失败的原因,removeChild只删除了孩子,而不是后代。

您想删除该包装div,或者根本不添加它。

在这里&#34;根本不添加它&#34;选项:

&#13;
&#13;
var markerDiv = document.createElement("div");
markerDiv.innerHTML = "<div id='MyCoolDiv' style='color: #2b0808'>123</div>";
document.getElementById("playerContainer").appendChild(markerDiv.firstChild);
// -------------------------------------------------------------^^^^^^^^^^^

setTimeout(function(){ 
    var myCoolDiv = document.getElementById("MyCoolDiv");
    document.getElementById("playerContainer").removeChild(myCoolDiv);
}, 1500);
&#13;
<div id="playerContainer"></div>
&#13;
&#13;
&#13;

或者不使用包装器(尽管解析HTML时非常方便):

&#13;
&#13;
var myCoolDiv = document.createElement("div");
// Don't reall need this: myCoolDiv.id = "MyCoolDiv";
myCoolDiv.style.color = "#2b0808";
myCoolDiv.appendChild(
  document.createTextNode("123")
);
document.getElementById("playerContainer").appendChild(myCoolDiv);

setTimeout(function(){ 
    // No need for this, we already have it from the above:
    // var myCoolDiv = document.getElementById("MyCoolDiv");
    document.getElementById("playerContainer").removeChild(myCoolDiv);
}, 1500);
&#13;
<div id="playerContainer"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

您孩子的直接父母是markerDiv,因此您应该从markerDiv调用remove,如下所示:

markerDiv.removeChild(myCoolDiv);

或者,您可能想要删除markerNode。由于该节点直接附加到videoContainer,因此可以使用以下命令删除它:

document.getElementById("playerContainer").removeChild(markerDiv);

现在,删除节点的最简单的一般方法是,如果你绝对相信你已经将它插入DOM中,那就是:

markerDiv.parentNode.removeChild(markerDiv);

这适用于任何节点(只需将markerDiv替换为不同的节点),并直接查找节点的父节点以便从中调用remove。如果您不确定是否添加了它,请在调用removeChild之前仔细检查parentNode是否为非null。

答案 2 :(得分:1)

正如其他人所说,myCoolDivmarkerDiv而非playerContainer的孩子。如果您想删除myCoolDiv但由于某种原因保留markerDiv,则可以执行以下操作

myCoolDiv.parentNode.removeChild(myCoolDiv);

JSFiddle

答案 3 :(得分:1)

当我将其更改为normal,div时,我以<> 作为父级将其包裹起来

答案 4 :(得分:0)

对我来说,将问题元素包装在另一个HTML标签中的提示很有帮助。但是,我还需要向该HTML标签添加密钥。例如:

// Didn't work
<div>
     <TroubledComponent/>
</div>

// Worked
<div key='uniqueKey'>
     <TroubledComponent/>
</div>

答案 5 :(得分:0)

我在 vue.js 项目中遇到了类似的问题。然后,我得到了将 fragment 包装器更改为 HTML 元素的提示。片段最常见的用例可能是当您需要返回多个元素时。使用片段这很容易,并且您不需要元素的典型包装器 div。它的简短语法是 <></>

基本上,我在 Vue 中使用了片段模式,然后出现了上述错误,使用 transition 动态渲染组件。看起来动态组件(需要多个元素)需要用 HTML 元素包装,而不是用片段包装。

// Vuejs
<transition
  name="router-anim"
  enter-active-class="animated animated-enter"
  mode="out-in"
  leave-active-class="animated animated-exit"
>
  <router-view /> // dynamic rendering based on current route using vue-router
</transition>