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

如何阻止Draft.js按下退格键时删除块并跳转光标到原子块textarea

实现方案

该需求完全可以实现,核心逻辑是拦截Draft.js的退格键事件,判断触发场景后阻止默认删除行为,再主动触发原子块内textarea的聚焦即可,具体操作步骤如下:

1. 提前拦截退格键事件

优先使用Draft.js的onKeyDown钩子在事件冒泡早期拦截退格操作,避免原子块被默认逻辑删除:

const handleKeyDown = (e) => {
  // 仅拦截退格键
  if (e.key !== 'Backspace') return;

  const selection = editorState.getSelection();
  // 仅处理光标在当前块最起始位置的场景:只有这个场景按退格会删除前一个块
  if (selection.getAnchorOffset() !== 0) return;

  const currentBlockKey = selection.getAnchorKey();
  const content = editorState.getCurrentContent();
  const blockMap = content.getBlockMap();
  const currentBlockIndex = blockMap.findKey(key => key === currentBlockKey);
  // 获取当前块的前一个相邻块
  const prevBlock = blockMap.get(blockMap.keySeq().get(currentBlockIndex - 1));

  // 前序块是原子块时拦截默认行为
  if (prevBlock?.getType() === 'atomic') {
    e.preventDefault();
    e.stopPropagation();
    // 触发原子块内textarea的聚焦
    focusAtomicTextarea(prevBlock.getKey());
  }
}

将上述方法绑定到Draft.js Editor组件的onKeyDown属性即可。

2. 给原子块的textarea绑定唯一标识

在原子块的渲染方法blockRendererFn中,给每个原子块的textarea添加和块key绑定的自定义属性,方便后续匹配DOM:

const blockRendererFn = (block) => {
  if (block.getType() === 'atomic') {
    return {
      component: (props) => {
        const blockKey = props.block.getKey();
        return (
          <div className="atomic-block-wrapper">
            {/* 用块key作为自定义属性值做唯一标识 */}
            <textarea 
              data-atomic-block-key={blockKey}
              placeholder="原子块输入区"
            />
          </div>
        )
      },
      editable: false // 原子块本身设为不可编辑,避免Draft.js接管内部输入逻辑
    }
  }
}

3. 实现textarea聚焦逻辑

通过块key匹配到对应DOM后触发聚焦,还可以根据需求自定义光标在textarea中的位置:

const focusAtomicTextarea = (blockKey) => {
  const targetTextarea = document.querySelector(`textarea[data-atomic-block-key="${blockKey}"]`);
  if (targetTextarea) {
    targetTextarea.focus();
    // 示例默认把光标放在textarea内容末尾
    targetTextarea.setSelectionRange(targetTextarea.value.length, targetTextarea.value.length);
  }
}

额外优化提示

  • 如果项目不推荐直接操作DOM,可以用React Ref替代属性查询:维护一个全局的Ref Map,key为原子块的key,value为对应textarea的ref,聚焦时直接从Map中取ref调用focus()即可,性能更好。
  • 如果需要实现从原子块textarea按退格跳转回主编辑器的逻辑,同理可以拦截textarea的onKeyDown事件,判断光标在textarea起始位置时,主动调用编辑器的focus方法,同时把编辑器选区设置到原子块的后一个块即可。

内容的提问来源于stack exchange,提问作者K. Tim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:27:05