javascript - 自动完成中的 React Material UI 打开模式失去焦点
问题描述
我正在使用material-ui lib,我需要一个自动完成功能,其中自动完成功能中的每个项目都是可点击的并打开一个模式。
一般结构如下:
const ModalBtn = () => {
...
return (
<>
<button ... (on click set modal to open)
<Modal ...
</>
);
}
const AutoCompleteWithBtns = () => {
return (
<Autocomplete
renderTags={(value, getTagProps) =>
value.map((option, index) => <ModalBtn />)
}
...
/>
);
}
注意,ModalBtn 是一个组件,不能分为 Button 和 Modal 两个组件。
问题是,当您单击模态内的按钮时 - 焦点保持在自动完成内,并且模态将永远不会获得焦点(如果我在模态内有输入 - 我不能在里面写任何东西)。
尝试了所有标准的自动完成/模态焦点相关道具(disableEnforceFocus
,disableEnforceFocus
等...),但没有任何效果。
这是一个有效的代码框示例。如您所见 - 如果您单击不在自动完成组件内的按钮 - 一切正常(您可以在输入字段内添加文本)。如果您单击自动完成内的按钮 - 模式内的输入字段不可编辑(您失去焦点)。
解决方案
Modal
从 内部渲染的问题Autocomplete
是事件从 传播Modal
到Autocomplete
。特别是,单击和鼠标按下事件的处理Autocomplete
方式都会导致您的情况出现问题。这主要是为了在您与Autocomplete
.
下面(来自https://github.com/mui-org/material-ui/blob/v4.9.11/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js#L842)是Autocomplete
代码的一部分妨碍你:
// Prevent input blur when interacting with the combobox
const handleMouseDown = (event) => {
if (event.target.getAttribute('id') !== id) {
event.preventDefault();
}
};
// Focus the input when interacting with the combobox
const handleClick = () => {
inputRef.current.focus();
if (
selectOnFocus &&
firstFocus.current &&
inputRef.current.selectionEnd - inputRef.current.selectionStart === 0
) {
inputRef.current.select();
}
firstFocus.current = false;
};
当鼠标按下事件发生在可聚焦元素上时,默认浏览器行为是让该元素接收焦点,但用于Autocomplete
调用的鼠标按下处理程序event.preventDefault()
会阻止此默认行为,从而防止鼠标按下事件改变焦点(因此焦点停留在Modal
自身上,如其蓝色焦点轮廓所示)。但是,您可以使用 tab 键成功地将焦点移动到 Modal 的 TextField,因为没有什么可以阻止焦点更改的机制。
即使您Autocomplete
单击. 当您打开时,这样做的效果是,当您单击 时,焦点会短暂移动到输入元素,但由于其“强制焦点”功能,焦点会立即返回到。如果您将属性添加到,您会看到当您单击(例如在 TextField 上)时,光标仍保留在.Autocomplete
Autocomplete
Modal
Modal
Autocomplete
Modal
disableEnforceFocus
Modal
Modal
Autocomplete
解决方法是确保这两个事件不会传播到Modal
. 通过调用event.stopPropagation()
上的单击和鼠标按下事件,Modal
当Autocomplete
这些事件发生在Modal
.
<Modal
onClick={event => event.stopPropagation()}
onMouseDown={event => event.stopPropagation()}
...
推荐阅读
- php - 如何使用 HTML 标签设置 PHP 代码样式?
- mysql - 如何从 talend 的 mysql 表中只读取一定百分比的记录
- amazon-web-services - 无法将 Auth.userAttributes 与联合登录一起使用
- python - 由于 pip 问题无法卸载 Numpy
- arrays - 将一堆字符串转换为数组并比较两个数组以获得两者的共同值
- python - Python - 使用递归计算总可能性
- domain-driven-design - 如何发布无 AggregateRoot 对象的事件?
- arrays - Excel VBA 循环遍历 10,000 组行,每组包含 20 行
- api - 微服务 API 设计。维护有状态的上下文
- android - Chromebook 上的 Androip 应用程序可以创建套接字 TCP 服务器、侦听连接并连接到 LAN 网络上的其他套接字服务器吗?