shuangmianxiaoQ / study-note

日常学习或工作笔记
6 stars 1 forks source link

React 中点击弹出层外面时关闭弹层的解决方案 #42

Open shuangmianxiaoQ opened 5 years ago

shuangmianxiaoQ commented 5 years ago

在使用antd的带弹出层的组件时,当点击弹出层以外的地方时,都会帮你关闭弹出层,最近在徐州中做的组件需要这样的功能,下面简单介绍下如何实现:

  1. 引用rc-util中的一些工具方法和react-domfindDOMNode方法
import addEventBodyListener from 'rc-util/lib/Dom/addEventListener';
import contains from 'rc-util/lib/Dom/contains';
import { findDOMNode } from 'react-dom';
  1. 找到需要关闭的弹出层,并为其绑定refs
<div visible={this.state.visible} ref={ref => (this.modalRef = ref)}>modal</div>
  1. componentDidUpdate声明周期中为document.body添加监听事件
componentDidUpdate() {
  if (this.state.visible) {
    this.clickOutside = addEventBodyListener(document.body, 'mousedown', this.onDocumentClick)

    return;
  }
}
  1. 定义onDocumentClick点击方法:如果当前点击的区域不在指定区域内,则关闭弹出层
onDocumentClick = e => {
  const modalRef = findDOMNode(this.modalRef);

  // 检测`e.target`是否不是`modalRef`或`modalRef`的子元素
  // 即点击目标不在弹出层上时,关闭弹出层
  // 必要时需要将触发弹出层打开的按钮也要算在弹出层以外的目标区域
  if (!contains(modalRef, e.target)) {
    this.setState({ visible: false })
  }
}
  1. 移除监听事件,componentDidUpdate中的监听也需要移除
componentDidUpdate() {
  if (this.clickOutside) {
    this.clickOutside.remove();
  }
}

componentWillUnmount() {
  if (this.clickOutside) {
    this.clickOutside.remove();
  }
}