富文本编辑器中如何正确插入并编辑表格?
我用 React + Draft.js 做富文本编辑器,现在想支持表格功能。但插入表格后,光标无法正常进入单元格,也不能用方向键在单元格间移动,感觉像是没被识别为可编辑区域。
我试过用原生 contentEditable 的 div 模拟,但和 Draft.js 的 EditorState 冲突了。下面是我目前插入表格的代码:
const insertTable = () => {
const table = '<table><tr><td></td><td></td></tr></table>';
const contentState = Modifier.replaceText(
editorState.getCurrentContent(),
editorState.getSelection(),
table,
null
);
setEditorState(EditorState.push(editorState, contentState, 'insert-table'));
};
这样插入的表格完全不能交互,有啥靠谱的方案吗?是不是得用自定义 block render?
Modifier.replaceText插入 HTML 字符串,它只会当成纯文本处理,不会解析成真正的 DOM 结构,更别谈交互了。核心问题在于:Draft.js 的 block 是独立的编辑单元,你想在 block 内部再搞出可编辑的单元格,必须用自定义 block render。
标准做法是这样的:
1. 先定义一个自定义 block type,比如叫
table2. 用
blockRendererFn捕获这个 block,返回一个自定义组件3. 表格组件内部用原生 contentEditable 实现编辑
几个关键点:
- 表格 block 的
editable要设为false,否则 Draft.js 会尝试把它当成普通文本编辑,导致行为混乱- 表格内部用独立的 contentEditable div,每个单元格独立处理
- 数据通过
onChange回写到 Draft.js 的 block data 中,保持状态同步- 方向键问题需要在表格组件的 keyDown 处理里自己实现,或者用键盘事件冒泡
如果你还需要在表格里支持更复杂的操作(比如合并单元格),原理是一样的,数据结构设计好就行。