gpt4 book ai didi

reactjs - react : How to capture focus when a focused child component unmounts

转载 作者:行者123 更新时间:2023-12-02 03:16:33 27 4
gpt4 key购买 nike

我有一个可以获得焦点的父组件。它使用这个焦点来提供键盘控制。该父组件可以生成一个子组件,该子组件同样可以获取焦点,以便它可以响应键盘事件。子组件监听的键盘事件之一是 <esc>这会导致子组件被卸载。

当子组件卸载时,焦点返回到 <body>文档的内容。

我的父组件如何检测何时发生这种情况并将焦点重新分配给自身?

到目前为止我所知道的:

  • React 的合成 onBlur处理程序确实从其子级获取冒泡模糊事件(与非合成事件不同)。但是,当焦点元素离开 DOM 时,不会触发模糊事件。
  • React 未实现 onFocusOut监听器,但如果我直接使用引用注册一个监听器,我确实会收到一个事件,告诉我 child 已卸载。但是,我无法区分 focusout由子进程卸载触发的事件,以及 focusout由用户点击不同的点击目标触发的事件。

编辑:我正在寻找一种不涉及父组件和子组件之间直接通信/耦合的解决方案。想象一下,在一棵任意深度嵌套的树中,可能有任意多个这样的 child 。

最佳答案

我最终使用 MutationObserver 解决了这个问题。

代码如下所示:

// It's possible for a child component to gain focus and then become
// unmounted. In that case, the browser will return focus to the `<body>`.
// In the following hook, use a `MutationObserver` to watch for that behavior
// and refocus the containing FocusTarget when it happens.
//
// I tried a number of other approaches using `focus/blur/focusin/focusout` on
// various DOM nodes, and was unable to find a solution which would trigger in
// this senario in Firefox. Therefore we use this `MutationObserver` approach.
useEffect(() => {
// Only create the `MutationObserver` within the currently focused target.
if (ref == null || windowId !== focusedWindowId) {
return;
}

const observer = new MutationObserver(mutations => {
// In the common case we won't have focused the body, so we can do this
// inexpensive check first to avoid calling the more expensive `O(n)`
// check of the individual mutations.
if (document.activeElement !== document.body) {
return;
}
if (mutations.some(mutation => mutation.removedNodes.length > 0)) {
ref.focus();
}
});

observer.observe(ref, {
subtree: true,
attributes: false,
childList: true
});

return () => observer.disconnect();
}, [windowId, focusedWindowId, ref]);

实际提交添加它:https://github.com/captbaritone/webamp/commit/2dca07ff0a97ad378a1a050513255d2ba129dbcd

关于reactjs - react : How to capture focus when a focused child component unmounts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55978535/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com