react hook自定义弹出框组件

先在组件中放置两个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>
	  )

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值