遮罩层事件穿透&完全禁止底部内容滑动(touch/app/wx/www)

在移动端开发中,当使用遮罩层弹出窗口时,通常需要阻止底部内容滑动。本文介绍了如何通过设置底部内容的overflow: hidden以及在遮罩层的touchmove事件上阻止默认事件来实现这一功能。在关闭遮罩层后恢复事件处理,确保在touch/wx/app环境中,即使webview存在弹性滚动,也能确保底部内容静止。

问题源自实践

在touch和app端如果需要做一个嵌入的html页面,如果需要做弹窗的话一般需要使用一个遮罩层的,然后在遮罩层设计弹出窗的内容,一般弹出窗是active之后,底部的内容是需要完全静止的(数据更新除外哈),在遮罩上进行的操作不能渗透到底部去,这种情况一般体现在遮罩层滑动需要禁止底部内容滑动,这种情况我们一般的处理方法是在弹出事件中设置底部内容的over-flow:hidden,在关闭遮罩层之后在解除禁止。在3w端包括在chrome的模拟器中可以使用。

那么问题就在于:在touch/wx/app中,我们相当于在webview内容元素中嵌入了一个html页面,webview中的内容和属性无法控制,但是一般移动端在顶部和底部都存在一个弹性滚动,在遮罩层弹出之后还是存在;

所以为了避免这种方法:可以为modal层的touchmove事件设置一个无效的响应事件,并且阻止默认事件,在关闭弹出层之后恢复,经过实际测试是可以达到完全静止底部内容包括容器自带的弹性滚动。由于在移动端才能测试这种效果,这里就通过代理来测试移动端了

<!docutype html>
<html>
    <head>
        <title>modal-test</title>
        <style type='text/css'>
            .bodyOver{
                overflow-y: hidden;
            }
            .contentBox{
                text-align: center;
                width:100vw;
                height: 200vh
            }
            .modal{
                display: none;
                position: fixed;
                top:0;
                left:0;
                width: 100vw;
                height: 100vh;
                background: rgba(66, 66, 66, 0.5);
                text-align: center;
                padding-top:20%;
            }
            .show{
                display: block;
            }      
        </style>
    </head>
    <body>
        <div class='contentBox'>
            <h2>this is content width height 200vh</h2>
            <Button id='toggleModal'>Modal</Button>
        </div>
        <div class='modal'>
            <button id='btnInModal'>click test </button>
        </div>
        <script>
            document.getElementById('toggleModal').addEventListener('click', () => {
                document.getElementsByClassName('modal')[0].classList.add('show');
                document.getElementsByTagName('body')[0].classList.add('bodyOver');
            })
            document.getElementById('btnInModal').addEventListener('click', () => {
                document.getElementsByClassName('modal')[0].classList.remove('show');
                document.getElementsByTagName('body')[0].classList.remove('bodyOver');
            })
        </script>
    </body>
</html>

 

### iOS 遮罩层事件穿透解决方案 在iOS系统中,遮罩层事件穿透问题通常表现为用户在点击或滑动遮罩层时,触发了遮罩层下方的内容。以下是几种常见的解决方法: 1. **通过JavaScript阻止默认行为和事件冒泡** 可以监听`touchmove`事件,并在事件处理函数中调用`event.preventDefault()`和`event.stopPropagation()`来阻止默认行为和事件冒泡。这种方法适用于需要完全禁用遮罩层下方滚动的场景[^1]。 ```javascript window.addEventListener(&#39;touchmove&#39;, (event) =&gt; { var e = event || window.event; e.preventDefault(); e.stopPropagation(); }, { passive: false }); ``` 2. **使用CSS属性`touch-action`** 为遮罩层设置`touch-action: none;`样式可以有效阻止触摸事件传递到遮罩层下方的内容。这种方法简单且高效,尤其适合组件化开发场景[^2]。 ```css .overlay { touch-action: none; } ``` 3. **通过Vue自定义指令控制页面滚动** 在Vue项目中,可以通过自定义指令实现遮罩层显示时锁定页面滚动的效果。具体做法是当遮罩层显示时,将`body`元素的`position`设置为`fixed`,并记录当前滚动位置;当遮罩层隐藏时,恢复`body`的样式和滚动位置[^4]。 ```javascript Vue.directive(&#39;fixed&#39;, { inserted() { let scrollTop = document.body.scrollTop || document.documentElement.scrollTop; document.body.style.cssText += &#39;position:fixed;width:100%;top:-&#39; + scrollTop + &#39;px;&#39;; }, unbind() { let body = document.body; body.style.position = &#39;&#39;; let top = body.style.top; document.body.scrollTop = document.documentElement.scrollTop = -parseInt(top); body.style.top = &#39;&#39;; } }); ``` 4. **调整DOM结构避免滚动穿透** 如果页面中存在`position: fixed`的元素嵌套在`scroll-view`中,可能会导致滚动穿透问题。将这些固定定位的元素移动到`scroll-view`外部,或者为它们添加`catch`属性,可以避免滚动穿透[^3]。 5. **结合`overscroll-behavior`优化滚动体验** 对于需要滚动的内容区域,可以通过设置`overscroll-behavior: none;`来防止滚动溢出行为影响其他内容。同时,确保内容区域的高度固定且允许垂直滚动[^2]。 ```css .scrollable-content { height: 500rpx; overflow-y: scroll; overscroll-behavior: none; } ``` 以上方法可以根据实际需求选择合适的方案进行实现。如果项目使用的是Vue框架,推荐优先考虑自定义指令的方式,因为它能够很好地与Vue的生命周期集成;如果是原生开发,可以直接通过CSS或JavaScript实现。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值