禁止遮罩层以下屏幕滑动

相信大家在做移动端开发的时候会经常遇到这种场景,需要适时的弹出遮罩(有时为了突出还会在外面加上蒙层),弹窗出现以后,为了追求良好的用户体验,遮罩以下的屏幕是禁止滑动的。在网上找了很多资料,大体就这两种做法,但都有不完善的地方。加上自己的思考和总结,想到一个办法,应该可以解决你的问题。

a)大众型

一般,大家想到的都是给body或者html添加overflow:hidden样式,当然height要设置成100%。这样在大多数机型上是可以的,但有个别的就是不起作用,我也不知道为什么(求知道的大神告知)。

b)高端型

因为这种需要弹窗遮罩的一般为移动端,pc很少会出现,就算是在pc里面上面那种方法也是可以解决的,所以可以考虑从移动端特有的滑动事件touchmove下手,当弹窗出现以后阻止该事件的默认行为不就行了吗,于是又有了下面的方法。

1 $(document).on("touchmove",function(e) {
2    e.preventDefault(); 
3 })

 

这种方法在移动端是可以解决滑动的问题,但有种情景就显得有点尴尬了,移动端屏幕本来就小,如果弹窗的内容过多也需要滑动(比如很长的活动规则),因为弹窗出现的时候已经禁止了滑动事件,那可如何是好????

c)改进型

在这种情形之下我想到了另外一种完美的办法,就是在禁止滑动之前先做一下判断,如果是在弹窗中触发的滑动事件就不阻止默认行为,其他地方同上。判断那部分我是通过类名判断的,通过其他的方法也是可以的(比如id),具体如下:

$(document).on("touchmove",function(e) {
   if(e.target.className.indexOf("shadeBox") >= 0) {
        e.preventDefault();      
    } 
})

上面的类名shadeBox是弹窗的蒙层的类名。也就是在蒙层上面滑动,事件是被禁止的,剩下的一部分就是弹窗了,所以弹窗的内容可以滑动。

以上有什么说的不对的,或者第三种方法还有不试用的情景的,还望指出,大家共同学习进步\(^o^)/~

 

更新说明:

  当我把这个东西分享给身边人用的时候,最后还是发现了问题,果然群众的眼睛还是雪亮的。问题如下:

当弹框内容过多,弹框也需要滑动的时候,因为弹框内部没有禁止touchmove,所以是可以滚动的,问题是当滚动到最底部继续往下滑的时候,奇怪的事情就发生了,此时页面还是会发生滑动,(在最上面的时候和这道理一样)。

我想的是可能弹框内部touchmove冒泡,然后到body上发生滑动。于是在弹框内部组织冒泡不就行了,于是做如下调整:

复制代码
复制代码
$(document).on("touchmove",function(e) {
   if(e.target.className.indexOf("shadeBox") >= 0) {
        e.preventDefault();      
    } else {
        e.stopPropagation();     
    }
})
复制代码
复制代码

修改以后,发现然并卵。。。

不知道为什么弹框内部并没有组织touchmove的冒泡,好奇怪。求知道的大神不吝告之。

现在的想法是,监听滑动事件,当滑动到底部或者最顶端时,禁止touchmove,并根据手指滑动的方向来释放开touchmove事件,即顶部的时候往下滑是放开事件,最底部的时候向上滑是放开事件。

虽然这边说的简单,但要实现这一功能确实太麻烦,如果只是在h5页面里面,完全没必要花这么多时间和精力在这个上面,如果是APP,追求极致那就另当别论了。

再说上面的情况是弹框内容过多的时候也需要滑动,如果弹框不需要滑动,跳出弹框以后直接全局禁用touchmove就好了,就没有上面的问题了。

不知道还有没有更好的做法?????

 

参考链接:http://www.cnblogs.com/gaohui/p/5819777.html


编辑补充:
今天终于找到一个完善的方法解决罩层的问题:思路大概是这样,当点击出现罩层时,将body的高度设置为当前设备高,并将top值记录下来,以便显示罩层出现前显示的内容。当点击关闭罩层时,将body的高度恢复,并滚动到记录的TOP位置。

/*---------罩层出现时---------*/
  var top = $("body").scrollTop();
  var h = $(window).height();
  $("body").css({
      "height": top + h + "px",
      "margin-top": "-"+top+"px"
  }).data("top",top);
/*------------------*/
/*---------隐藏罩层---------*/
  var top = $("body").data("top");
  $("body").css({
      "height":"auto",
      "margin-top": "0"
  }).scrollTop(top);
/*------------------*/



### 如何在 UniApp 中设置弹出层的遮罩范围 在 UniApp 开发中,弹出层的遮罩范围可以通过多种方式实现。以下是几种常见的解决方案: #### 方法一:通过 `mask` 属性控制遮罩层 UniApp 提供了内置的 `popup` 组件,该组件支持通过 `mask` 属性启用或禁用遮罩层。如果需要调整遮罩层的行为,可以直接操作此属性。 ```html <uni-popup ref="popup" type="center" mask="true"> <!-- 弹出层内容 --> </uni-popup> ``` 在此基础上,还可以进一步定制遮罩层样式,例如改变透明度或颜色[^2]。 --- #### 方法二:使用事件修饰符阻止默认行为 为了防止遮罩层下方的内容被触碰或滚动,可以在遮罩层绑定触摸事件并使用 `.stop.prevent` 修饰符。这种方法能够有效拦截用户的交互动作。 ```html <view class="blackuai" v-if="popNum != ''" @click="rest" @touchmove.stop.prevent="moveHandle"></view> ``` 上述代码片段展示了如何利用 `@touchmove.stop.prevent` 来阻止页面滑动[^1]。 --- #### 方法三:动态修改页面滚动状态 另一种常见的方式是在弹窗显示时临时更改页面的滚动状态。具体做法是,在打开弹窗的同时将 `document.body.style.overflow` 设置为 `'hidden'`;而在关闭弹窗时恢复其原始值。 ```javascript // 显示弹窗 const showDialog = () => { show.value = true; document.body.style.overflow = 'hidden'; // 禁止页面滚动 }; // 关闭弹窗 const close = () => { show.value = false; document.body.style.overflow = ''; // 恢复页面滚动 }; ``` 这种方式适用于全局范围内屏蔽背景区域的操作[^4]。 --- #### 方法四:CSS 定位与层级管理 合理运用 CSS 的定位和 z-index 可以精确设定遮罩层覆盖的目标范围。例如,通过固定定位 (`position: fixed`) 和较高的 z-index 值 (如 `z-index: 999`) 实现完全覆盖整个屏幕的效果。 ```css .mask-layer { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 999; } ``` 此外,还需注意某些特殊场景(如 TabBar),可能需要额外处理才能确保遮罩层能正确覆盖这些原生控件[^5]。 --- ### 总结 以上四种方法各有优劣,实际开发过程中可以根据项目需求灵活选用。对于简单的遮罩效果,推荐优先尝试官方提供的 `popup` 组件及其相关配置项;而对于更复杂的需求,则可结合 JavaScript 动态调整 DOM 样式以及监听用户手势等方式达成目标。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值