Modal框的显示隐藏

遮罩层

1.如果将遮罩层直接放在body元素中,可以设置position:absolute,然后设置宽高撑满屏幕;此时position:absolute相对于body进行绝对定位;
2.如果遮罩层不是body的直接子元素,可以设置position:fixed,相对窗口进行定位

 .mask1{
            position: absolute;
            height: 100%;
            width: 100%;
            background-color: #000;
            opacity: 0.5;
        }

        .mask2{
            position: fixed;
            height: 100%;
            width: 100%;
            left: 0;
            top: 0;
            background-color: greenyellow;
            opacity: 0.2;
        }

在这里插入图片描述


 - position:relative,相对定位,是指元素相对于正常文档流的位置进行定位;
	1.不设置left/right或者bottom/top属性时,定位不生效;
	2.只是位置相对发生变化,元素不会脱离文档流
	3.元素设置相对定位后,会提高层级,可以覆盖相对于原本同级的元素
	4.块级元素依旧是块级元素,行内元素依旧是行内元素;

 - position:absolute,绝对定位,是指元素相对于最近一个position定位的元素进行绝对定位,如果在此之前没有positon定位的元素,则会一直寻找到body元素,并相对于body进行定位;
	1.不设置left/right或者bottom/top属性时,定位不生效;
	2.开启后,元素会脱离文档流;
	3.元素属性可能发生变化,行内元素会变成块元素,块的宽高被内容撑开;
	4.元素层级相对原本元素层级会提高;
	5.absolute相对于最近的第一个position包含元素进行定位,如果没有,则以body为包含块进行定位;
	
 - fixed定位,则是相对于窗口的定位,但是不要忘记设置left和top属性值,否则定位失效;

Modal层点击空白处触发事件

方法一:设置全局监听,判断监听的元素中是否含有内部元素

  1. 获取modal中的DOM元素,判断点击的元素是否包含该两个元素,因为点击任何一个元素不可能包含另一个元素,所以如果同时包含说明,点击的是最外层的遮罩;
  2. 关闭遮罩后记得清楚监听函数,否则产生内存泄漏
  const clickHideMask = e => {
    const eleBlockCenter = document.getElementsByClassName('detail-data');
    const eleBlockRight = document.getElementsByClassName('detail-data-table');
    // 获取modal中的DOM元素,判断点击的元素是否包含该两个元素,因为点击任何一个元素不可能包含另一个元素,所以如果同时包含说明,点击的是最外层的遮罩;
    if (
        e.target.contains(eleBlockCenter[0]) &&
        e.target.contains(eleBlockRight[0])
    ) {
      showMask(false); // 关闭遮罩层
    }
};
 
 // 关闭遮罩后记得清楚监听函数,否则产生内存泄漏
   useEffect(() => {
    if (maskVisible) {
      document.body.addEventListener('click', clickHideMask);
    } else {
      document.body.removeEventListener('click', clickHideMask);
    }
  }, [maskVisible]);

// 相关元素
   <div  id="detail-wrap">
	    <div className="detail-data"></div>
	    <div className="detail-data-table"></div>
   </div>

方法二:最外层设置点击事件,内部元素阻止冒泡;

DOM事件流中,点击modal中的元素,会冒泡到最外层元素中,此时只需要将包含元素禁止冒泡,就不会触发最外层的点击事件;

 // 遮罩层内元素,阻止冒泡,最外层遮罩设置点击事件,触发关闭遮罩
    < div
        id="detail-wrap"
        onClick={() => {
            setExitCurrentPage(true);
                showMask(false);
        }}
    >
        <div
            className="detail-data"
            onClick={e => {
                e.stopPropagation();
                e.nativeEvent.stopImmediatePropagation();
            }}
        >
            {maskBlock}
        </div>
        <div
            className="detail-data-table"
            onClick={e => {
                e.stopPropagation();
                e.nativeEvent.stopImmediatePropagation();
            }}
        >
        </div>
    </div>

Modal消失后触发其他事件

这种场景除了在一个点击事件中包含所有的事件处理方式之外,还可以将点击事件拆开,一个点击事件分为mousedown事件和mouseup事件,一个完整的click事件需要包含该两个事件;

  <div class="bottom-wrap">
        底部元素
        <div class="div-wrap">
            modal框
            <div class="div-box1">元素一</div>
            <div class="div-box2">元素二</div>
        </div>
    </div>

    <script>
        var a = document.querySelector('.div-wrap')
        a.addEventListener('mouseup', function () {
            a.style.visibility = 'hidden'
        })

        var b = document.querySelector('.bottom-wrap')
        b.addEventListener('mousedown', function () {
            b.style.background = 'pink'
        })
    </script>

如图点击事件拆分成mousedown和mouseup事件,同样也可以用这两种方法去做modal层的隐藏,但是依旧需要在元素上阻止冒泡
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值