react next.js点击任何区域关闭弹框,以点击按钮弹出下拉菜单为例

 

import { useState,useEffect,useCallback,useRef,memo} from 'react'
import Icon from '../icon';
import  '../../public/css/ui/drop_down.css';
function drop_down(props){
    const {menu,name,icon,current}=props;

//menu=[{
//   id:0,
//   name_en:"全部"
//},id:1,name_en:"菜单一"}]
//name:默认名
//icon
//current为当前选中项索引

    const bodyBox = useRef(null);
    const [isbtn, setisbtn] = useState(0);
    const [menuIndex, setmenuIndex] = useState(0);
    function bindshow(e){
        let isbtn1=isbtn?0:1
        setisbtn(isbtn1);
    }
    const onClickOutsideHandler = useCallback(
        (e) => {
            if(bodyBox.current){
                if(!bodyBox.current.contains(e.target)){
                    setisbtn(0)
            }}
        },[]
      );
      function Checktype(index, e){
          console.log(index,e)
          setmenuIndex(index)
         setisbtn(0);
        //console.log("menu[index]",menu[index])
        e.nativeEvent.stopImmediatePropagation();
        props.getChildValue && props.getChildValue(menu[index]);
      }
    useEffect(()=>{
        if(current && current!=undefined){
            setmenuIndex(current);
        }
        document.addEventListener('click', onClickOutsideHandler);
    },[])
    return(
        <>
        <div className="ui_drop_down_btn_bg" ref={bodyBox}>
    <div className="ui_drop_down_btn" onClick={bindshow}><Icon className={icon} addclass="ui_icon"></Icon><span>{menuIndex==0 ?name:menu[menuIndex].name_en}</span><Icon className="icon-Angle-down" addclass="arrow"></Icon></div>
            {isbtn?
            <div className="ui_drop_down_menu">
                {menu.map((item,index)=>(
                    <div key={item.id} className={`ui_drop_down_menu_li ${menuIndex==index?'ui_drop_down_menu_li_on':''}`} onClick={Checktype.bind(this, index)}><span>{item.name_en}</span><Icon className="icon-Check"></Icon></div>
                ))}
            </div>
            :''}
        </div>
        </>
    )
}
export default memo(drop_down)

//用法:
<Drop_down menu={[{
   id:0,
   name_en:"全部"
},id:1,name_en:"菜单一"}]}
name="type all"
icon="icon-list"
></Drop_down>
//drop_down.css
.ui_drop_down_btn_bg{
    position: relative;
}
.ui_drop_down_btn{
    padding:6px 10px;
    background: #f5f5f5;
    border-radius: 5px;
    margin-right: 20px;
    display: inline-flex;
    justify-content: center;
    align-items: center;

    
}
.ui_drop_down_btn .ui_icon{
    display: block;
    height: 24px;
    line-height: 24px;
    font-size: 24px;
    margin-right: 6px;
}
.ui_drop_down_btn .arrow{margin-left: 6px;}

.ui_drop_down_menu{
    width: 250px;
    position: absolute;
    left: 0;
    top: 50px;
    background: #ffffff;
    border-radius: 5px;
    background-color: rgba(255, 255, 255, 1);
    box-shadow: 0px 15px 50px -25px rgba(106, 106, 106, 1);
    border: 1px solid rgba(42, 42, 42, 1);
    padding: 15px 0px;
    z-index: 99;
}

.ui_drop_down_menu_li{
    height: 36px;
    line-height: 36px;
    padding: 0 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.ui_drop_down_menu_li .icon{display: none;font-size: 16px;}
.ui_drop_down_menu_li_on{
    background: #f5f5f5;
}
.ui_drop_down_menu_li_on .icon{display: block;}
.ui_drop_down_menu_li:hover{background: #f5f5f5;}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

web16888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值