我想创建一个可以确定我的编辑器是否具有焦点的函数:
function hasFocus(editor: LexicalEditor) {
const hasFocus = editor.getEditorState().read(() => {
// return $...
})
return hasFocus
}
Run Code Online (Sandbox Code Playgroud)
我浏览了源代码和文档,但没有找到可以直接检测到这一点的方法。在我的测试中,Selection对象似乎无法可靠地确定编辑器是否专注于 DOM。
那么,如何检测编辑器焦点呢?
我发现我可以订阅FOCUS_COMMAND并BLUR_COMMAND在本地状态发生变化时更新它们:
const useEditorFocus = () => {
const [editor] = useLexicalComposerContext()
// Possibly use useRef for synchronous updates but no re-rendering effect
const [hasFocus, setFocus] = useState(false)
useEffect(
() =>
editor.registerCommand(
BLUR_COMMAND,
() => {
setFocus(false)
return false
},
COMMAND_PRIORITY_LOW
),
[]
)
useEffect(
() =>
editor.registerCommand(
FOCUS_COMMAND,
() => {
setFocus(true)
return false
},
COMMAND_PRIORITY_LOW
),
[]
)
return hasFocus
}
Run Code Online (Sandbox Code Playgroud)
这似乎足够了,但我仍然想知道是否可以直接从事实来源(EditorState)获取信息,而不是通过副作用来跟踪它。
扩展你的答案
我们引入命令作为处理输入事件的主要机制,因为我们将默认通过阻止它们event.preventDefault(并且用户可能仍然想监听它们或覆盖它们)。
专注并不是绝对必要的,但遵循相同的命令模式感觉很自然。
// Commands are subscriptions so the default state is important!
const [hasFocus, setHasFocus] = useState(() => {
return editor.getRootElement() === document.activeElement);
});
useLayoutEffect(() => {
setHasFocus(editor.getRootElement() === document.activeElement);
return mergeRegister(
editor.registerCommand(FOCUS_COMMAND, () => { ... }),
editor.registerCommand(BLUR_COMMAND, () => { ... }),
);
}, [editor]);
Run Code Online (Sandbox Code Playgroud)
如果可能的话,您应该useState完全避免,因为 React 重新渲染的成本很高(如果您不需要在该值更改时显示不同的内容)。
请注意,EditorState 没有有关输入是否获得焦点的信息。
| 归档时间: |
|
| 查看次数: |
4751 次 |
| 最近记录: |