如何在编辑器从 DOM 中移除后删除 CKeditor 实例
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
我已经 在 jsfiddle 上重新创建了该问题 你会看到代码:
- 从 textarea 创建 ckeditor 实例
- 删除父 dom 元素
- 创建新的 dom 元素
- 尝试删除所有当前实例
- 创建一个新的 ckeditor 实例
第 4 步生成错误。
n.b. 有关删除 ckeditor 实例的问题与仍然存在的 dom 元素有关,在这种情况下 dom 已被删除。我无法控制被删除的 dom 元素。
有没有办法将事件绑定到当其父 dom 元素被删除时触发的 ckeditor?我认为即使是这样我仍然会遇到这个问题。有人知道吗?
n.b. 我在该项目的其他地方使用 jQuery,因此即使我没有在 ckeditor 代码中使用它,涉及 jQuery 的解决方案也是合适的。
更新:
我确实尝试将实例设置为
null
,这确实有效,但不会终止在 CKeditor 实例上创建的对象。即
CKEDITOR.htmlDataProcessor
(使用 Chrome 开发工具中的“配置文件 -> 堆快照”可以很好地演示此问题)
更新:
感谢 @oleq 提供的信息,我查看了讨论但不知道如何添加,因此在此处更新:
请查看 dom 更改前后的内存配置文件图像。
您会看到 CKEDITOR 属性的大小确实增加了。
我注意到
CKEDITOR.instances.editor1.element.$
存储了 ckeditor 已绑定/触发的元素。是否会检查该元素上是否存在现有的 ckeditor 实例,这会破坏现有的
CKEDITOR.htmlDataProcessor
等对象并在将新实例添加到文本区域之前重新创建?
这听起来像是合适的事情吗?或者这被视为极端情况是否意味着其优先级太低?如果被认为是合理的解决方案,我很乐意投入工作并提出请求?
问题的根本原因似乎已在 https://github.com/ckeditor/ckeditor-dev/pull/200 中得到修复
简而言之 - 在您调用 destroy 之前,iFrame 元素已从 DOM 中分离/移除,这导致 ckEditor getFrame 方法返回 null。
在升级到最新的 ckEditor 版本之前,我的解决方法是将 destroy 放在 try/catch 中。
控制 CKEditor 实例销毁的算法并非为处理极端情况而设计的。错误在
wysiwygarea 插件中的特定点
处抛出,因为基本上
editor.window.getFrame()
返回
null
。
这是一个极端情况, 已在 CKEditor 错误跟踪器上讨论过 。