作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个可以获得焦点的父组件。它使用这个焦点来提供键盘控制。该父组件可以生成一个子组件,该子组件同样可以获取焦点,以便它可以响应键盘事件。子组件监听的键盘事件之一是 <esc>
这会导致子组件被卸载。
当子组件卸载时,焦点返回到 <body>
文档的内容。
我的父组件如何检测何时发生这种情况并将焦点重新分配给自身?
到目前为止我所知道的:
onBlur
处理程序确实从其子级获取冒泡模糊事件(与非合成事件不同)。但是,当焦点元素离开 DOM 时,不会触发模糊事件。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/
我是一名优秀的程序员,十分优秀!