在CKEditor中使用ckeditor5-typing开发软键盘:删除键实现难题
解决CKEditor软键盘删除键功能问题
我之前在CKEditor里折腾自定义输入逻辑的时候,也碰到过删除键的坑——直接用原生DOM操作根本不太行,必须跟着CKEditor的API规则来!结合你的现有代码,给你整理个可行的方案:
核心思路
CKEditor采用模型(Model)和视图(View)分离的架构,不能直接操作DOM来删除内容,得用它提供的model层API来修改,同时要阻止原生删除事件避免冲突。
具体代码实现
把你的现有keydown监听逻辑补上删除键的处理:
ClassicEditor .create(document.querySelector('#editor')) .then(editor => { console.log(editor); editor.editing.view.document.on('keydown', (event, data) => { const keyPressed = data.domEvent.key; // 你已实现的字符映射逻辑 const mappedChar = getMappedCharacter(keyPressed); if (mappedChar) { // 阻止原生输入,插入映射后的字符 data.preventDefault(); editor.model.change(writer => { writer.insertText(mappedChar, editor.model.document.selection); }); } // 新增:处理删除键(Backspace和Delete) else if (keyPressed === 'Backspace' || keyPressed === 'Delete') { // 先阻止原生删除行为,避免和自定义逻辑冲突 data.preventDefault(); editor.model.change(writer => { const selection = editor.model.document.selection; if (selection.isCollapsed) { // 情况1:光标没有选中内容,删除单个字符 const position = selection.getFirstPosition(); if (keyPressed === 'Backspace') { // 删除光标前的字符,注意不能在段落开头删除 if (!position.isAtStart) { const prevPos = writer.createPositionBefore(position.nodeBefore); writer.remove(writer.createRange(prevPos, position)); } } else { // 删除光标后的字符,注意不能在段落结尾删除 if (!position.isAtEnd) { const nextPos = writer.createPositionAfter(position.nodeAfter); writer.remove(writer.createRange(position, nextPos)); } } } else { // 情况2:选中了一段内容,直接删除选中范围 writer.remove(selection.getFirstRange()); } }); } }); }) .catch(error => { console.error(error); });
关键细节说明
- 阻止原生事件:必须调用
data.preventDefault(),不然CKEditor自带的删除逻辑会先触发,导致你的自定义删除失效或者出现重复删除的问题。 - 模型层操作:用
editor.model.change()包裹修改操作,这是CKEditor的标准做法,能保证数据模型和视图同步,同时支持撤销/重做功能。 - 选区判断:区分“光标未选中内容”和“选中一段内容”两种场景,覆盖用户的常规删除操作。
如果你的软键盘是虚拟键盘(不是物理按键触发),只要模拟keydown事件时正确传递key值为'Backspace'或'Delete',这段逻辑同样适用。
内容的提问来源于stack exchange,提问作者sometimes24
相关产品推荐
相关产品推荐

