在页面中对某一个事情详细说明,这个时候需要弹层来显示,弹层内容较长需要滚动,但是当滚动到底部时body会滚动,当我们关闭弹层时页面阅读的位置发生了变化,用户又要重新找到阅读的地方,这样用户体验极不友好。
网上找了很多的资料,最后都会有一些问题,然后就自己想办法解决下!
首先解决body会滚动的问题:
html, body { height: 100%; overflow: auto ;-webkit-overflow-scrolling: touch;}
这样做的原因是显示弹层给body设置样式overflow:hidden有效(禁用滚动条这样解决了安卓,到ios问题还是一样);
在ios中弹层滚动到底部时,用户先释放掉当前的滚动的事件(停止触摸让滚动回弹等执行完),再执行向下滚动时事件会被他的父级捕获,如果用户操作比较快(ios一般都有300ms的过渡动画), 马上再直接向上滚动,这个时候依然滚动的是父级。因为我们当前弹层触摸事件丢失了, 弹层就没有办法滚动了(这个时候要再次释放触摸滚动事件才可以向上滚动)。
这个时候我们强大的js就要上马了!!
<template>
<div class="main-layout-container" v-show="visible">
<div class="main-layout-shade"></div>
<div class="main-layout-box">
<div ref="layoutContent" @touchmove="touchMove" @touchstart="touchStart" :style="{'height':contentHeight}" class="main-layout-content"><slot></slot></div>
</div>
</div>
</template>
data(){ return{ visible: false, isTouch: true, startY: 0, moveY: 0, }},
methods:{
touchStart(){
this.startY = event.touches[0].clientY;
},
touchMove(){
let sDom = this.$refs.layoutContent;
let sTop = sDom.scrollTop || sDom.pageYOffset || 0;
let sGao = sDom.scrollHeight - sDom.clientHeight;
this.moveY = event.touches[0].clientY;
if(sTop === 0){
if(this.moveY < this.startY){
this.isTouch = false;
}else{
this.isTouch = true;
} if(this.isTouch){
event.preventDefault();
} }
if(sGao <= sTop){
if(this.moveY > this.startY){
this.isTouch = false;
}else{
this.isTouch = true;
}
if(this.isTouch){
event.preventDefault();
}
}},
}
<style>
.main-layout-container{position: fixed; left: 0; top: 0; z-index: 90; width: 100%; height: 100%; overflow: hidden;}
.main-layout-shade{ position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 98; background: rgba(0,0,0,.5);}
.main-layout-box{ position: absolute; left: 0; bottom: 0; width: 100%; height: 100%; max-height: 100%; z-index: 99; overflow: hidden; background: #fff;}
.main-layout-content{ padding: 0; margin: 0; border: none; overflow-y: scroll; overflow-scrolling: touch; -webkit-overflow-scrolling: touch;}
</style>
上面几乎解决了ios滚动的所有问题,只是滚动到底部没有回弹的效果了!!!