如何可靠判断Slate编辑器当前是否处于聚焦状态?
可靠判断Slate编辑器聚焦状态的方案
你遇到的ReactEditor.isFocused(editor)不稳定问题,大多是因为Slate内部焦点追踪和React渲染周期不同步,嵌套元素选中时焦点事件传递未被正确捕获导致的。以下是几种可靠的实现方式:
方案一:基于DOM元素的焦点检测
直接通过编辑器的DOM引用判断焦点是否在编辑器范围内(包括嵌套元素),稳定性最高:
- 先获取编辑器的DOM引用:
const editorRef = useRef(null); <Slate editor={editor} initialValue={initialValue}> <Editable ref={editorRef} // 其他配置项 /> </Slate>
- 编写判断逻辑:
const isEditorFocused = () => { const activeElement = document.activeElement; return editorRef.current && editorRef.current.contains(activeElement); };
只要焦点处于编辑器DOM树内的任何元素,都会返回true,完美适配嵌套元素场景。
方案二:手动维护聚焦状态
通过监听编辑器的focus/blur事件,用React状态管理聚焦状态,确保焦点变化时触发重渲染:
const [isFocused, setIsFocused] = useState(false); <Editable onFocus={() => setIsFocused(true)} onBlur={() => setIsFocused(false)} // 其他配置项 />
如果需要结合Slate的选择状态(比如编辑器聚焦但无选中内容的场景),可以扩展判断逻辑:
const isEditorEffectivelyFocused = isFocused && !!editor.selection;
方案三:修复ReactEditor.isFocused的渲染同步问题
若坚持使用Slate自带方法,可通过订阅编辑器的焦点事件强制组件更新,保证状态同步:
const [, setState] = useState({}); useEffect(() => { const handleFocus = () => setState(prev => ({ ...prev })); const handleBlur = () => setState(prev => ({ ...prev })); ReactEditor.on(editor, 'focus', handleFocus); ReactEditor.on(editor, 'blur', handleBlur); return () => { ReactEditor.off(editor, 'focus', handleFocus); ReactEditor.off(editor, 'blur', handleBlur); }; }, [editor]); // 此时ReactEditor.isFocused的返回值会同步渲染 const focused = ReactEditor.isFocused(editor);
内容的提问来源于stack exchange,提问作者Xen_mar
相关产品推荐
相关产品推荐

