CK Editor 5:在单个编辑器实例中混合可编辑与只读段落
需求可行性与实现方案
这个需求完全可以实现,核心是利用CKEditor 5的视图层API控制段落的可编辑状态,并通过事件拦截防止用户修改只读段落。以下是具体实现步骤:
1. 编写自定义插件控制只读段落
创建一个简单的插件,在编辑器初始化后自动标记偶数段落为只读,并拦截对这些段落的修改操作:
class ReadonlyParagraphsPlugin extends Plugin { init() { const editor = this.editor; // 编辑器内容加载/变更后,同步段落可编辑状态 editor.model.document.on('change:data', () => { editor.editing.view.document.getRoot().getChildren().forEach((node, index) => { if (node.is('element', 'p')) { // 索引从0开始,偶数索引对应原问题的奇数段落(可编辑),奇数索引对应偶数段落(只读) const isReadonly = (index + 1) % 2 === 0; node.setAttribute('contenteditable', isReadonly ? 'false' : 'true'); } }); }, { priority: 'high' }); // 阻止对只读段落的任何修改操作 editor.editing.view.document.on('beforeinput', (evt) => { const selection = editor.editing.view.document.selection; const selectedNode = selection.getFirstPosition().parent; if (selectedNode.is('element', 'p') && selectedNode.getAttribute('contenteditable') === 'false') { evt.preventDefault(); } }); // 防止通过键盘删除只读段落 editor.editing.view.document.on('keydown', (evt) => { const selectedNode = editor.editing.view.document.selection.getFirstPosition().parent; if (selectedNode.is('element', 'p') && selectedNode.getAttribute('contenteditable') === 'false') { // 拦截删除、退格等修改键 if (['Delete', 'Backspace', 'Cut'].includes(evt.key)) { evt.preventDefault(); } } }); } }
2. 注册插件并初始化编辑器
将自定义插件添加到编辑器的插件列表中,完成初始化:
ClassicEditor .create(document.querySelector('#editor'), { plugins: [Essentials, Paragraph, Bold, Italic, ReadonlyParagraphsPlugin], toolbar: ['bold', 'italic'] }) .catch(error => { console.error(error); });
3. 关键注意事项
- 事件优先级设置为
high,确保你的状态控制逻辑优先于编辑器默认逻辑执行。 - 除了
beforeinput事件,还需要拦截键盘操作(如删除、退格),避免用户通过键盘快捷键修改只读段落。 - 如果编辑器内容是动态加载的,插件会在内容变更后自动重新应用只读规则,确保状态始终符合要求。
在线测试说明
你可以在CKEditor 5的官方在线沙箱中测试:将上述插件代码复制到沙箱的自定义脚本区域,初始化编辑器后即可看到效果——奇数段落可正常编辑,偶数段落无法修改。
内容的提问来源于stack exchange,提问作者Web Dev Newbie
相关产品推荐
相关产品推荐

