You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:34:35