CKEditor 5 - 获取编辑器实例

15

我正在从CKEditor 4.7迁移到5。

在CKE4中,我会这样做: CKEDITOR.replace('text_area'); 然后在另一个JS函数中,我可以通过 CKEDITOR.instances.text_area.getData()来获取数据。

但似乎CKE5没有类似ClassicEditor.instances的函数。

我知道我可以将编辑器实例存储为全局JS变量,但我正在使用的代码在通用函数中创建编辑器,因此我不能只创建一个全局变量,因为我事先不知道编辑器的名称。在屏幕上也可能同时有几个编辑器活动的情况。

在CKE5中是否没有类似旧版instances的功能,允许我仅通过它所替换的文本区域的id获取编辑器实例?

如果有内置且得到更好支持的功能,那么我可能会创建自己的全局数组来保存编辑器实例,但我不想这么做。

4个回答

27

这个问题在如何从CKEDITOR5实例中获取数据已经有了答案,但是我们在这里考虑一种有多个编辑器实例的情况。

我想我可以创建自己的全局数组来保存编辑器实例,但如果有内置且支持更好的东西,我宁愿不这样做。

没有编辑器实例的存储库。我们可以添加它,但我们认为这不是一个必要的功能。实际上,人们在CKEditor 4中习惯了这个功能,所以他们从未想过或学会如何自行管理他们的编辑器。

此外,没有单个实例存储库的原因是根本没有中央单例对象。您可以实现多个编辑器类,它们不必彼此了解。要想出一个存储库,我们需要再次将这些东西集中起来。

因此,正如您自己指出的那样,存储所有实例的简单方法是通过拥有这些实例的全局(在您的应用程序或模块中全局,而不一定是“全局JS变量”)映射。

这些实例的键可以是您初始化编辑器的元素的ID:

const editors = {}; // You can also use new Map() if you use ES6.

function createEditor( elementId ) {
    return ClassicEditor
        .create( document.getElementById( elementId ) )
        .then( editor => {
            editors[ elementId ] = editor;
        } )
        .catch( err => console.error( err.stack ) );
}

// In real life, you may also need to take care of the returned promises.
createEditor( 'editor1' );
createEditor( 'editor2' );

// Later on:
editors.editor1.getData();

如果您不为DOM元素分配ID会怎样? 如果您使用ES6,则这不是问题。 元素(如其他对象)可以作为Map键。

const editors = new Map();

function createEditor( elementToReplace ) {
    return ClassicEditor
        .create( elementToReplace )
        .then( editor => {
            editors.set( elementToReplace, editor );
        } )
        .catch( err => console.error( err.stack ) );
}

// In real life, you may also need to take care of the returned promises.
createEditor( textarea1 );
createEditor( textarea2 );

// Later on:
editors.get( textarea1 ).getData();

如果您无法使用ES6,则需要做更多的工作 - 例如,在创建编辑器的元素上动态分配一些 data-editor-id 属性。


非常感谢您的详细解释!我们还没有开始使用ES6,所以看起来您第一个推荐的实现方法正是我需要的。非常感谢! - BlackBelt2025
编辑器是否会从编辑器映射中删除?这样做不会在SPA中创建内存泄漏吗? - nawlbergs

9

这并不是我第一次尝试提醒自己如何在只能通过开发者控制台访问DOM的生产网站上访问CKEditor实例,所以这是给自己的一个提醒 ;)

https://ckeditor.com/docs/ckeditor5/latest/builds/guides/faq.html#how-to-get-the-editor-instance-object-from-the-dom-element

可以使用 ckeditorInstance 属性来访问编辑器实例,该属性可用于CKEditor 5正在使用的可编辑元素。您可以通过例如.ck-editor__editable类访问此DOM元素。

// A reference to the editor editable element in the DOM.
const domEditableElement = document.querySelector( '.ck-editor__editable' );
    
// Get the editor instance from the editable element.
const editorInstance = domEditableElement.ckeditorInstance;
    
// Now you can use the editor instance API.
editorInstance.setData( '<p>Hello world!<p>' );

截至2022年4月,正确的文档链接为:https://ckeditor.com/docs/ckeditor5/latest/support/faq.html#how-to-get-the-editor-instance-object-from-the-dom-element - Edouard

1

我想补充一点,如果您想在Drupal 9.5+中实现这一点,那么Drupal会为我们创建一个Map。 Drupal.CKEditor5Instances将返回包含所有编辑器的Map。

然后,您可以通过Drupal.CKEditor5Instances.get("{editorId}").getData()来实现相同的结果。


0
使用jQuery和类选择器运行多个编辑器的副本:
$( '.editor' ).each( function() {
    InlineEditor
        .create( this )
        .catch( error => {
            console.error( error );
        } );
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接