目录
方案一 事件修饰符 + overscroll-behavior
有一层遮罩蒙层覆盖在body上时,当我们滚动遮罩层,它下面的内容也会跟着一起滚动,看起来好像是上面的滚动事件穿透到下面的DOM元素上一样,我们称之为滚动穿透。
.stop
: 各平台均支持, 使用时会阻止事件冒泡,在非 H5 端同时也会阻止事件的默认行为使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 @click.prevent.self
会阻止所有的点击,而 @click.self.prevent
只会阻止对元素自身的点击。
若需要禁止蒙版下的页面滚动,可使用 @touchmove.stop.prevent="moveHandle"
,moveHandle
可以用来处理 touchmove
的事件,也可以是一个空函数。
- // 在父级元素添加重写滚动事件 @touchmove.stop.prevent="() => { }"
- <view class="list" @touchmove.stop.prevent="() => { }">
- <uni-data-picker placeholder="请选择项目" popup-title="请选择所属项目" :localdata="items" v-model="classes" @change="onchange"></uni-data-picker>
- </view>
overscroll-behavior,MDN介绍看这里
当对话框中含有可滚动内容时,一旦滚动至对话框的边界,对话框下方的页面内容也开始滚动了——这被称为“滚动链”。
默认情况下,当触及页面顶部或者底部时(或者是其他可滚动区域),移动端浏览器倾向于提供一种“触底”效果,甚至进行页面刷新。你可能也发现了,当对话框中含有可滚动内容时,一旦滚动至对话框的边界,对话框下方的页面内容也开始滚动了——这被称为“滚动链”。
先看一张MDN官方的属性值及其描述的图。
auto: 默认值,但是要注意,这里的auto是包含移动端的触底效果的
contain:本文的主要讲解属性
none:禁止滚动效果(包含触底)
官方示例是添加属性之后,为了方便掩饰,我使用了默认值进行录制。
而这也是我们经常遇到的情况,在有弹窗时,滚动弹窗会导致页面跟随滚动。
跟随官方示例,如果希望做到滚动弹窗而不影响页面时,我们只需要在摊床上添加属性oversroll-behavior:contain即可以实现滚动弹窗而不影响页面的效果了。
这段代码需要加在最外层的父级元素上面:
- /deep/ .container {
- // 在真正的滚动区域设置 阻断滚动穿透
- overscroll-behavior-y: contain !important;
- }
照例,看一眼兼容情况。
不能说是完全没法用,只能说是有点惨烈。
不过主流的Chrome、Firefox、edge的兼容都是还可以的。
所以如果有需要应用的话,还是值得考虑的。
部分不兼容的页面最多是没有这个效果,但是主流浏览器的用户都可以正常访问使用。
优点:编码简单
缺点:由于设置了overflow:hiden,底部元素会默认滚动到顶部,意味着之前滚动的距离会被清空
1.添加在uitil.js文件中
- // 阻止页面滚动
- export function stop(){
- var box=function(e){passive: false ;};
- document.body.style.overflow='hidden';
- document.addEventListener("touchmove",box,false);
- }
- // 允许页面滚动
- export function move(){
- var box=function(e){passive: false };
- document.body.style.overflow=''; // 出现滚动条
- document.removeEventListener("touchmove",box,false);
- }
2.绑定在原型上,在main.js
- import {stop,move} from '@/utils/utils.js'
- Vue.prototype.stop = stop
- Vue.prototype.move = move
3.在打开弹窗和关闭弹窗时使用this调用(打开使用this.stop(),关闭使用this.move()