先在组件中放置两个div,一个是需要弹出的组件的div,另一个是触发组件的div。
//触发div
<div style={{ width: '200px', height: '200px', background: 'red', }} >按钮块</div>
//弹出的div
<div style={{ width: '50px', height: '50px', background: 'blue' }} >
123
</div>
给触发的div设置点击事件
const showModel = () => {
document.addEventListener('mousedown', (e) => hiddeModel(e), false);
}
<div style={{ width: '200px', height: '200px', background: 'red' }} onClick={() => { showModel() }} >按钮块</div>
给弹出的div设置ref,点击触发div的时候,,再设置一个model,触发弹出div的显示,再修改之前的触发div的点击事件。
import React, { useRef, useState } from 'react';
import { findDOMNode } from 'react-dom'
const [model, setModel] = useState()
const hiddeModel = (e) => {
if (divEle.current) {
let result = findDOMNode(divEle.current).contains(e.target);
if (!result) {
setModel()
document.removeEventListener('mousedown', (e) => this.handleClickOutside(e), false);
}
}
}
const showModel = () => {
setModel("123")
document.addEventListener('mousedown', (e) => hiddeModel(e), false);
}
<div ref={divEle} style={{ display: model ? '' : "none",width: '50px', height: '50px', background: 'blue' }} >
这时候我们已经基本成功了,点击触发div,可以显示弹出div,点击其他位置,可以隐藏弹出div。
但还是有2个问题
一:点击弹出div,无法隐藏弹出div
解决:在弹出div上加一个点击事件
const handClidk = () => {
setModel()
}
<div ref={divEle} style={{ display: model ? '' : "none",width: '50px', height: '50px', background: 'blue' }} onClick={() => handClidk()} >
二:点击触发div后,弹出div显示成功,但是再次点击触发div,无法隐藏弹出div。
原因:我们可以看到弹出div闪了一下,是因为我们点击触发div的时候,触发了两个点击事件,一个是隐藏弹出div的事件,一个是显示弹出div的事件。
解决:给触发div加一个pointerEvents属性,当model有值的时候,也就是弹出div显示的时候,我们把触发div的点击事件关闭。
<div style={{ width: '200px', height: '200px', background: 'red', pointerEvents: model ? 'none' : '' }} onClick={() => { showModel() }} >按钮块</div>
完整示例
import React, { useRef, useState } from 'react';
import { findDOMNode } from 'react-dom'
const IndexPage = () => {
const [model, setModel] = useState()
const divEle = useRef(null);
const showModel = () => {
setModel("123")
document.addEventListener('mousedown', (e) => hiddeModel(e), false);
}
const hiddeModel = (e) => {
if (divEle.current) {
let result = findDOMNode(divEle.current).contains(e.target);
if (!result) {
setModel()
document.removeEventListener('mousedown', (e) => this.handleClickOutside(e), false);
}
}
}
const handClidk = () => {
setModel()
}
return (
<div>
<div style={{ width: '200px', height: '200px', background: 'red', pointerEvents: model ? 'none' : '' }} onClick={() => { showModel() }} >按钮块</div>
<div ref={divEle} style={{ display: model ? '' : "none", width: '50px', height: '50px', background: 'blue' }} onClick={() => handClidk()}>
123
</div>
</div>
)
}