# NotFoundError: Node.removeChild: 要移除的节点不是此节点的子节点

**URL:** <https://meta.discourse.org/t/notfounderror-node-removechild-the-node-to-be-removed-is-not-a-child-of-this-node/154739>\
**Category:** Development\
**Created:** [2020年六月13日 09:50 UTC](https://meta.discourse.org/t/notfounderror-node-removechild-the-node-to-be-removed-is-not-a-child-of-this-node/154739 "2020-06-13T09:50:02Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![magjac](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/magjac/32/174488_2.png) [@magjac](https://meta.discourse.org/u/magjac)\
**Post date:** [2020年六月13日 09:50 UTC](https://meta.discourse.org/t/notfounderror-node-removechild-the-node-to-be-removed-is-not-a-child-of-this-node/154739/1 "2020-06-13T09:50:02Z")

</div>

我开发了一个主题组件：

> **[GitHub - magjac/discourse-d3-graphviz: Discourse theme component for rendering animated...](https://github.com/magjac/discourse-d3-graphviz)**
>
> Discourse theme component for rendering animated Graphviz graphs using DOT source code

它将 BBCode 替换为 SVG。这在编辑器预览中也能正常工作。

我的问题是，在某些情况下，当我在编辑器中输入字符时会出现错误：

`NotFoundError: Node.removeChild: 要移除的节点不是该节点的子节点`

我相当确定这与移除某些元素有关，因为如果我不移除任何内容，就不会出现该错误。

**编辑** ：错误并非在移除时发生，而是在移除后在编辑器中输入第一个字符时出现。

我的问题是：移除元素是否不被允许？

如果允许，您是否知道为什么会发生这个错误？

我意识到这有点模糊。如有需要，我可以提供更多细节。

堆栈跟踪如下所示：

 ![Screenshot from 2020-06-13 11-34-55](https://global.discourse-cdn.com/meta/original/3X/5/0/50ea1e50cf02e772f96b664fce846c7191be65b6.png)

---

<div class="post-metadata">

**Author:** ![magjac](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/magjac/32/174488_2.png) [@magjac](https://meta.discourse.org/u/magjac)\
**Post date:** [2020年六月13日 11:54 UTC](https://meta.discourse.org/t/notfounderror-node-removechild-the-node-to-be-removed-is-not-a-child-of-this-node/154739/2 "2020-06-13T11:54:17Z")

</div>

**编辑 2：** 我移除的不只是元素，有时只移除文本节点。

---

<div class="post-metadata">

**Author:** ![magjac](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/magjac/32/174488_2.png) [@magjac](https://meta.discourse.org/u/magjac)\
**Post date:** [2020年六月13日 13:47 UTC](https://meta.discourse.org/t/notfounderror-node-removechild-the-node-to-be-removed-is-not-a-child-of-this-node/154739/3 "2020-06-13T13:47:23Z")

</div>

我可以用这个简单的主题组件复现此问题：

```plaintext
<script type="text/discourse-plugin" version="0.8">

  api.decorateCooked($elem => {
    if ($elem.get(0).className == 'd-editor-preview') {
      const $paragraphs = $elem.children('p');
      $.each($paragraphs, (paragraphIndex, paragraph) => {
        paragraph.remove();
      });
    }
  });

</script>

```

1. 创建一个新主题
2. 开始输入。在输入第二个字符时，错误会出现在开发控制台中。

---

<div class="post-metadata">

**Author:** ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)\
**Post date:** [2020年六月16日 11:12 UTC](https://meta.discourse.org/t/notfounderror-node-removechild-the-node-to-be-removed-is-not-a-child-of-this-node/154739/4 "2020-06-16T11:12:42Z")

</div>

作曲家预览使用 Ember 来渲染 `cooked` 内容。看起来该错误来自 Ember 渲染引擎，这很可能是因为 DOM 被其他操作修改导致引擎混淆。

为避免此问题，建议您不要 `remove()` 任何节点，而是使用 `display:none;` 或类似方式将其隐藏。

---

<div class="post-metadata">

**Author:** ![magjac](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/magjac/32/174488_2.png) [@magjac](https://meta.discourse.org/u/magjac)\
**Post date:** [2020年六月16日 11:18 UTC](https://meta.discourse.org/t/notfounderror-node-removechild-the-node-to-be-removed-is-not-a-child-of-this-node/154739/5 "2020-06-16T11:18:10Z")

</div>

谢谢。这确实是我一直在考虑的变通方法，但如果您能确认这是否确实是一个 bug，我将不胜感激。

---

<div class="post-metadata">

**Author:** ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)\
**Post date:** [2020年六月16日 11:26 UTC](https://meta.discourse.org/t/notfounderror-node-removechild-the-node-to-be-removed-is-not-a-child-of-this-node/154739/6 "2020-06-16T11:26:03Z")

</div>

作曲家预览是 Ember 渲染与自定义 ‘decorateCooked’ 函数的不寻常组合。这似乎是该实现的一个特性。我们目前没有任何计划改变其工作方式，尤其是因为现有的解决方案既简洁又实用。

---

<div class="post-metadata">

**Author:** ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)\
**Post date:** [2020年十月28日 09:38 UTC](https://meta.discourse.org/t/notfounderror-node-removechild-the-node-to-be-removed-is-not-a-child-of-this-node/154739/7 "2020-10-28T09:38:10Z")

</div>

@j.jaffeux 我注意到你在使用 WidgetGlue 时，将 `cleanUp` 函数传递给了 `api.cleanupStream`。

> <https://github.com/discourse/discourse-group-timezones/blob/main/javascripts/discourse/initializers/initialize-discourse-group-timezones.js.es6#L14-L17>

当我在 widget 附加后尝试在编辑器中写入内容时，遇到了 OP 中描述的错误。值得注意的是，当我使用 `WidgetGlue.appendTo()` 定位原始的 `div data-wrap` 后，该 div 完全消失了……

编辑：已解决。我为 Widget 创建了一个临时的 `<div>` 节点供其消耗，这样我就可以保留 `[wrap=dice]` div 存活。

```plaintext
  // elem: <div class="d-wrap" data-wrap="dice">

  //- const glue = new WidgetGlue("dice-result", register, attrs);
  elem.innerHTML = "";
  //- glue.appendTo(elem);
  const sacrificial = document.createElement("div");
  elem.appendChild(sacrificial);
  attachDiceWidget(sacrificial, attrs);

```
