react 点击空白处隐藏弹出层

时间:2022-07-13 10:21:51

点击空白处隐藏弹出层的原理是:在 document 上绑定事件来隐藏弹出层,这样点击任何元素的时候都会冒泡到 document 上,都会执行隐藏弹出层的功能。然后我们在不需要隐藏弹出层的元素上阻止冒泡即可。

class Select extends Component {
constructor(props) {
super(props);

this.state = {
selected: props.list[
0],
showList:
false
};

this.showList = this.showList.bind(this);
}

componentDidMount() {
// 在 document 上绑定点击事件,隐藏弹出层
document.addEventListener('click', (e) => {
this.setState({
showList:
false
});
});
}

showList(e) {
// 使用 react 的 e.stopPropagation 不能阻止冒泡,需要使用 e.nativeEvent.stopImmediatePropagation,这里我们对其进行封装,方便多次调用
this.stopPropagation(e);
this.setState({
showList:
!this.state.showList
});
}

selectList(i) {
const selected
= this.props.list[i];
this.setState({
selected: selected,
showList:
false
});
this.props.onChange(selected);
}

// 封装后的阻止冒泡功能
stopPropagation(e) {
e.nativeEvent.stopImmediatePropagation();
}

render() {
const { list }
= this.props;
const { selected, showList }
= this.state;
return (
<div className="hp-select">
<span className="hp-select__text">{selected.text}</span>
<span className="hp-select__btn" onClick={this.showList}></span>
<div
className
="hp-select__list"
style
={{ display: showList ? 'block' : 'none' }}
// 方便的调用封装冒泡功能来阻止冒泡
onClick={this.stopPropagation}
>
<ul>
{
list
&& list.map((item, i) => {
return <li key={item.value} onClick={this.selectList.bind(this, i)}>{item.text}</li>;
})
}
</ul>
</div>
</div>
);
}
}