如何在编辑器从 DOM 中删除后删除 CKeditor 实例

How to remove CKeditor instances after the editor has been removed from the DOM

SO 上有一些关于如何删除 CKeditor 实例的相关问题,大多数使用 .destroy()。但是,当编辑器仍在 dom 中时,这很好。我遇到 CMS 添加文本区域的情况,我正在将其转换为 CKeditor。 cms 移动 dom 中的元素(在不相关的事件上)。

我可以将一个事件绑定到那个不相关事件的 complete 发出,这样 CKeditor 就可以重新初始化。一切正常,但是当我删除那些遗留的实例时,我得到了错误,这就是我尝试的方式:

for (var name in CKEDITOR.instances) {
    CKEDITOR.instances[name].destroy(true);
}

但它产生错误:

Uncaught TypeError: Cannot read property 'clearCustomData' of null

我有 recreated the issue on a jsfiddle 你会看到代码:

  1. 从文本区域创建一个 ckeditor 实例
  2. 删除父 dom 元素
  3. 创建新的 dom 元素
  4. 试图删除所有当前实例
  5. 创建一个新的 ckeditor 实例

第 4 步产生错误。

n.b. 有关删除 ckeditor 实例的相关问题与仍然存在的 dom 元素相关dom 的情况已被删除。我无法控制要删除的 dom 元素。

有没有办法将事件绑定到 ckeditor,当它的父 dom 元素被删除时触发?我假设即使是这样,我仍然会遇到这个问题。有人有什么想法吗?

n.b. 我在这个项目的其他地方使用jQuery ,所以涉及 jQuery 的解决方案是合适的,即使我没有在 ckeditor 代码中使用它。

更新:

我确实尝试将实例设置为 null,这确实有效,但不会终止在 CKeditor 实例上创建的对象。即 CKEDITOR.htmlDataProcessor (在 Chrome 开发工具中使用 'Profiles -> Heap snapshot' 是一个很好的问题演示)

更新:

感谢@oleq 提供的信息,我查看了讨论但不知道如何添加,所以在此处更新:

请查看 dom 更改前后内存配置文件的图像。

您会看到 CKEDITOR 属性的大小确实增加了。

我注意到 CKEDITOR.instances.editor1.element.$ 存储了 ckeditor 绑定 to/fired 的元素。是否会检查该元素上现有的 ckeditor 实例,这会破坏现有的 CKEDITOR.htmlDataProcessor 等对象并在将新实例添加到文本区域之前重新创建?

这听起来是否合适,或者这被视为边缘案例的事实是否意味着它的优先级太低?如果认为是合理的解决方案,我很乐意投入工作并提出请求?

控制 CKEditor 实例销毁的算法不是为处理边缘情况而设计的。错误在 that specific point in wysiwygarea plugin 处抛出,因为基本上 editor.window.getFrame() returns null.

这是一个边缘案例,already discussed on CKEditor bug tracker

问题的根本原因似乎已在 https://github.com/ckeditor/ckeditor-dev/pull/200

中修复

简而言之 - iFrame 元素是 detached/removed 来自 DOM,然后调用 destroy 导致 ckEditor getFrame 方法返回 null。

在升级到最新的 ckEditor 版本之前,我的解决方法是将销毁放在 try/catch。