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

我开发了一个主题组件:

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

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

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

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

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

我的问题是:移除元素是否不被允许?

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

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

堆栈跟踪如下所示:

编辑 2: 我移除的不只是元素,有时只移除文本节点。

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

<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. 开始输入。在输入第二个字符时,错误会出现在开发控制台中。

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

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

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

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

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

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

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

  // 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);