Javascript 当输入或子项未使用React聚焦时,如何隐藏div?

Javascript 当输入或子项未使用React聚焦时,如何隐藏div?,javascript,reactjs,Javascript,Reactjs,因此,我有一个自定义的搜索和选择组件,用于呈现父容器中包装的输入和结果列表: <div className='wrapper'> <input /> <div className='results'> <div>Result Item</div> <div>Result Item</div> <div>Result Item</div> <di

因此,我有一个自定义的搜索和选择组件,用于呈现父容器中包装的输入和结果列表:

<div className='wrapper'>
  <input />
  <div className='results'>
    <div>Result Item</div>
    <div>Result Item</div>
    <div>Result Item</div>
    <div>Result Item</div>
    <div>Result Item</div>
  </div>
</div>
以及功能:

handleFocus = () => {
  this.setState({
    isExpanded: true
  });
}
这很有效。我面临的问题是让它在适当的时候结束。只有当用户在
包装器
div
外部实际单击时,它才会关闭。当我需要它保持打开状态时:

  • 如果用户单击任何结果项
  • 如果用户专注于输入,则单击结果项
  • 如果用户单击一个结果项,则关注输入
因此,基本上,
wrapper
div中的任何交互都应该保持打开状态

为了实现这一点,我在包装器周围放置了一个模糊事件:

<div className='wrapper' tabIndex='1' onBlur={this.handleBlur}> ... </div>
问题是,当单击一个项目或聚焦于输入时,事件触发的已聚焦的
包装器会被拿走,这是它应该触发的,但我无法阻止它在我不希望它触发时触发

我尝试使用
document.activeElement
ReactDOM.findDOMNode
混合使用来比较活动元素,但它仍然不起作用。有什么想法吗

下面是我试图实现的一个基本示例(它使用不同的函数绑定方法,但这一点仍然有效):

class SearchAndSelect扩展React.Component{
构造函数(){
超级();
此.state={
isExpanded:错误
}
this.handleBlur=this.handleBlur.bind(this);
this.handleFocus=this.handleFocus.bind(this);
}
车把{
这是我的国家({
isExpanded:错误
})
}
手焦点(){
这是我的国家({
isExpanded:是的
})
}
render(){
返回(
{this.state.isExpanded&&Results}
);
}
}
ReactDOM.render(,document.getElementById('container'))

我也做过类似的事情,通过在下面放置一个div来实现:

<div className='closer' onClick={this.handleBlur...
<div className='wrapper'...

.closer:
position: absolute
width/height:100%

此高阶组件应能帮助您:


请看下面的示例。您需要使用它增强包装器组件,然后将
this.setState({isExpanded:false})
放入
handleClickOutside()
方法。

如果发生模糊事件时鼠标落在包装器内,您可以说希望忽略模糊。我使用this.ignoreBlur来指示是否应该忽略模糊-我没有使用state,因为您不希望或不需要它来导致重新渲染。我还包括移出包装器以重置ignoreBlur,以防鼠标落下,您将永远无法获得包装器的鼠标上升事件,这将使ignoreBlur永久为真

<div className='wrapper' onMouseDown={this.setIgnoreBlur} onMouseUp={this.clearIgnoreBlur} onMouseOut={this.clearIgnoreBlur} onBlur={this.handleBlur}>
  <input />
  <div className='results'>
    <div>Result Item</div>
    <div>Result Item</div>
    <div>Result Item</div>
    <div>Result Item</div>
    <div>Result Item</div>
  </div>
</div>

setIgnoreBlur = () => {
  this.ignoreBlur = true;
}

clearIgnoreBlur = () => {
  this.ignoreBlur = false;
}

handleBlur = () => {
  if (this.ignoreBlur) return;
  this.setState({
    isExpanded: false
  });
}

结果项
结果项
结果项
结果项
结果项
setIgnoreBlur=()=>{
this.ignoreBlur=true;
}
clearIgnoreBlur=()=>{
this.ignoreBlur=false;
}
车把杆=()=>{
如果(this.ignoreBlur)返回;
这是我的国家({
isExpanded:错误
});
}
我更新了你的小提琴:

<div className='closer' onClick={this.handleBlur...
<div className='wrapper'...

.closer:
position: absolute
width/height:100%
<div className='wrapper' onMouseDown={this.setIgnoreBlur} onMouseUp={this.clearIgnoreBlur} onMouseOut={this.clearIgnoreBlur} onBlur={this.handleBlur}>
  <input />
  <div className='results'>
    <div>Result Item</div>
    <div>Result Item</div>
    <div>Result Item</div>
    <div>Result Item</div>
    <div>Result Item</div>
  </div>
</div>

setIgnoreBlur = () => {
  this.ignoreBlur = true;
}

clearIgnoreBlur = () => {
  this.ignoreBlur = false;
}

handleBlur = () => {
  if (this.ignoreBlur) return;
  this.setState({
    isExpanded: false
  });
}