最近做一个需求,想要点击空白的地方关闭弹窗,网上找了好久,没有一个能用的,后面用ref实现了,记录一下
原理就是用ref来获取DOM元素,进行比对,如果被点击的event是弹窗本身或者包含弹窗,就不处理,如果弹窗之外的区域,就关闭
react 的实现demo如下:
interface IDemoState {
open: boolean;
}
class Demo extends React.Component<{}, IDemoState> {
public inputRef = React.createRef<HTMLDivElement>();
constructor(props: IDeliveryLocationProps) {
super(props);
this.state = {
open: false,
};
}
componentDidMount() {
this.getAddress();
document.addEventListener('click', this.handleDocumentClick);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleDocumentClick);
}
/**点击弹窗之外的地方弹窗消失 */
handleDocumentClick = (e: Event) => {
if (!this.inputRef.current) {
return;
}
/**点击弹窗之内的,不关闭;点击弹窗之外的,关闭 */
if (!this.inputRef.current.contains(e.target as Node)
&& this.inputRef.current !== e.target) {
this.setState({
open: false,
});
}
};
render() {
return (
<div >
<div ref={this.inputRef}>
{ this.state.open && <span >弹窗</span>}
</div>
<div >
弹窗之外
</div>
</div>
);
}
}
最关键的就是这个判断了
if (!this.inputRef.current.contains(e.target as Node)
&& this.inputRef.current !== e.target)
如果是弹窗区域或者包含弹窗区域,则不处理;反之,则关闭弹窗