视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
vue解决弹出蒙层滑动穿透问题的方法
2020-11-27 22:07:13 责编:小采
文档


最近开发过程中遇到一些小问题(似乎问题总是那么多),但一直没什么时间去优化与解决。程序员不能被业务绑架,有时间还是花点在代码上😀,开始这次的vue尝试吧。

【遇到的问题】

在一个可滑动列表页弹出一个全屏蒙层,蒙层固定,中间一块显示消息框,当用手滑动蒙层空白处时,滑动事件会穿透到底部列表页,导致列表页的滑动。

【要实现的目标】

1. 滑动蒙层空白处不让滑动事件穿透。  

2. 当蒙层消息框文字多时,要让文字可上下滑动。

要实现的效果其实如下:

【实现思路】

1. vue提供的@touchmove.prevent可以用来阻止滑动,但是这个方法会对其内的子div的滑动事件也禁止掉了,这样会导致中间文字无法滑动。如果没有中间滑动需求,用@touchmove.prevent实现是一个很好的方法。

2. 蒙层设为fixed悬浮在最上,底部列表设置overflow-y: hidden;这样可以列表内容就不可以滑了,但实际过程中没有效果,于是想到继续往列表父div向上追溯,对body和html标签设置相关样式,这样就控制住了底部列表滑动问题。

3. 蒙层空白处点击事件与中间文字点击事件处理,防止事件冒泡带来其他bug。

【相关实现代码】

1. html代码都是比较简单,列表页for循环实现;蒙层用一个变量控制其显示和隐藏。但这里有几个注意点: a. 给上面列表的div动态绑定了noScroll class,它的作用是当消息蒙层显示时切换到相关的css样式; b. 弹出的全屏蒙层,加有点击事件是为了点空白处让蒙层消失,但这里对显示的每行文字还加了@click.stop="messageTitleClick(num)"这个方法,为什么加它呢——是因为蒙层空白处的点击方法对整个蒙层都生效,在文字上加上这个方法可以屏蔽掉蒙层点击方法的影响,即使这个方法里什么也不做它也是有作用的,另外这个方法上加了stop是为了防止它的点击事件穿透到后面的div。代码如下:

<!-- 列表 -->
 <div :class="{noScroll: isShowPopup}">
 <div class="item" v-for="num in 50" @click="itemClick(num)">
 <div style="width:100%">点击item{{num}}</div>
 </div>
 </div>

   <!-- 蒙层 -->
 <div v-if="isShowPopup" class="popup" @click="popUpEmptyClick()">
 <div class="message">
 <p class="message-title" v-for="num in 30" @click.stop="messageTitleClick(num)">
 消息提示 {{num}}
 </p>
 </div>
 </div>

2. 给整个列表动态绑定的css如下

/* 当前蒙层显示时生效 */
.noScroll {
 overflow-y: hidden;
}

3. 给列表整个div动态绑定.noScroll 后,底部列表照样可以滑动,所以考虑继续向上追溯。利用watch监听蒙层是否显示,当显示时,设置body相应样式;但蒙层消失时,body样式恢复。但是在vue里怎么操作body里,虽然vue是数据驱动的,不提倡直接操作Dom。但此刻我也是没什么好办法了,就直接操作Dom了。如下:

watch: {
 isShowPopup(newVal, oldVal) {
 if (newVal == true) {
 let cssStr = "overflow-y: hidden; height: 100%;";
 document.getElementsByTagName('html')[0].style.cssText = cssStr;
 document.body.style.cssText = cssStr;
 } else {
 let cssStr = "overflow-y: auto; height: auto;";
 document.getElementsByTagName('html')[0].style.cssText = cssStr;
 document.body.style.cssText = cssStr;
 }

 // 下面需要这两行代码,兼容不同浏览器
 document.body.scrollTop = this.pageScrollYoffset;
 window.scroll(0, this.pageScrollYoffset);
 }
 }

【补充】

最好去查看完整的demo代码,因为后续代码对真机上一些滑动问题进行了修复补充,包括处理一些滚动条位置等。

【Demo地址】

手动将路由切到 /three 就是此页示例

https://github.com/LiJinShi/wechat_back_vue

下载本文
显示全文
专题