[英]Prevent auto focus of a material-ui popover element
我正在尝试创建一个搜索匹配列表,该列表会随着用户在查询中键入而更新。 但是,我无法弄清楚如何保持对输入元素的关注。 弹出窗口总是聚焦。 我曾尝试使用 refs 以编程方式设置焦点,但我无法为无状态函数组件(我假设这是我的 TextField 输入)提供 ref。
这是行为的 gif。 https://imgur.com/a/JVskedr
请注意弹出窗口如何窃取焦点并阻止用户进一步输入。
<TextField
id='contact'
label='Contact Name'
className={classes.textField}
margin='normal'
ref={this.nameInput}
onChange={this.handleContactSearch.bind(this)}
value={this.state.contactSearch}
/>
<Popover
open={Boolean(anchorEl)}
anchorEl={anchorEl}
onClick={this.handlePopoverClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center'
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center'
}}
autoFocus={false}
>
<List>{this.createContactList()}</List>
</Popover>
这些是相关的功能:
handleContactSearch(event) {
this.handlePopoverClick(event);
this.setState({ contactSearch: handleText(event) });
this.props.filterContacts(
event.target.value,
this.props.accountInfo.AccountName
);
}
handlePopoverClick = event => {
this.setState({
anchorEl: event.currentTarget
});
};
handlePopoverClose = () => {
this.setState({
anchorEl: null
});
};
如何使 TextField 元素保持焦点,以便用户可以不间断地输入查询?
将“disableAutoFocus”、“disableEnforceFocus”道具传递给您的弹出框。 它对我有用!
<Popover
open={Boolean(anchorEl)}
// pass these props to the popover component
disableAutoFocus={true}
disableEnforceFocus={true}
>
发生这种情况的原因是每次在您的<TextField>
触发onChange={this.handleContactSearch.bind(this)}
事件时,您都会调用this.showPopover(event)
。
为了解决这个问题,您需要找到一种方法,只调用一次this.showPopover(event)
。
我能够使用<TextField/>
上的autoFocus={true}
和onFocus={this.showPopover}
事件的组合使其工作。 唯一的问题是当您第一次打开模态时,弹出窗口将显示为空。 我在文本字段上使用了ref
并使用了条件来设置弹出框的不透明度,因此它仅在文本字段中有值时才显示。
也许不是最终的解决方案,但它有效,至少应该让你朝着正确的方向前进。
<div className={classes.paper}>
<TextField
id="contact123"
label="Contact Name"
className={classes.textField}
margin="normal"
onChange={this.handleContactSearch.bind(this)}
value={this.state.contactSearch}
autoFocus={true}
onFocus={this.showPopover}
inputRef={input => (this.tf = input)}
/>
<Popover
open={Boolean(anchorEl)}
anchorEl={document.getElementById("contact123")}
onClick={this.closePopover}
anchorOrigin={{
vertical: "bottom",
horizontal: "center"
}}
transformOrigin={{
vertical: "top",
horizontal: "center"
}}
style={{ opacity: this.tf && !this.tf.value.length ? 0 : 1 }}
>
<List>{this.state.contactSearch}</List>
</Popover>
<div>
<Button color="primary" className={classes.saveButton}>
Save
</Button>
</div>
</div>
沙盒:工作演示
这种方法的替代方法是使用Popper
、 ClickAwayListener
和Backdrop
组件。 使用Popper
可以让您专注于输入字段并继续输入。 解决方案大致如下:
class Foo extends React.Component {
inputRef = React.createRef(),
render() {
const { open, searchValue } = this.state
<RootRef rootRef={this.inputRef}>
<div className={classes.container}>
// You may be able to use TextField as well
<FormControl
onKeyDown={//set open = false}
onClick={// set open = true (e.g. only when searchValue !== '' }
>
<InputBase
value={searchValue}
onChange={this.handleSearchValueChange}
inputRef={this.inputRef}
/>
</FormControl>
<Popper anchorEl={this.inputRef.current} open={open} >
<ClickAwayListener onClick={//set open = false} onClickAway={//set open = false}>
Popover content
</ClickAwayListener>
</Popper>
</div>
</RootRef>
}
}
不是一个工作示例,但展示了如何解决在打开 popover/popper 时能够输入输入的问题。
您可以将 onKeyDown 属性添加到每次用户键入时将关闭它的弹出窗口,并将 onKeyUp 属性添加到再次弹出弹出窗口的搜索输入。 不是最好的解决方案,但它对我有用。
<InputBase
autoFocus={true}
value={searchText}
onChange={(e) => handleSearch(e)}
onKeyUp={e => setAnchorEl(e.currentTarget)}
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
inputProps={{ "aria-label": "search" }}
/>
{searchResult && (
<Popover
disableAutoFocus
className={classes.pop}
onKeyDown={handleClose}
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "center",
}}
transformOrigin={{
vertical: "top",
horizontal: "center",
}}
>
{searchResult.map((song, i) => {
return (
<Link to={`/Songs/${song.unique_id}?Artist=${song.artist_id}`}>
<ListItem>
<IconButton variant="h6" >
<PlayCircleFilledRounded/>
</IconButton>
{song.title}
</ListItem>
</Link>
);
})}
</Popover>
)}
</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.