H5弹窗底层滑动
H5弹窗底层滑动
背景
- 产品提出H5 弹出窗滑动时,底层页面也会跟随滑动,需要调整禁止底层滑动,增加用户体验。
问题产生原因
- ios 滑动时有回弹效果
- 顶层元素滑动默认行为
解决办法
- 阻止元素的默认(此方法会阻止整个页面滑动,导致在弹出窗内容也不能滑动。)
- 影藏body高度,使页面高度小于弹窗高度(次方法会影响页面布局,暂时不做记录)
代码块
- 💡阻止元素默认行为
- 使用 addEventListener 监听 touchmove 事件
注:当弹窗消失时要 移除 touchmove 事件监听以免影响页面滑动
// 简单屏蔽弹窗滑动
function noSwiperTouch(className, isAdd = true) {
if(isAdd) {
document.querySelector(className).addEventListener('touchmove', noTouch);
} else {
document.querySelector(className).removeEventListener('touchmove', noTouch);
}
}
function noTouch(e) {
e.preventDefault();
}
优化可以使内部元素可以滑动
// 阻止背景
let iosTrouchFnEl = null;
function iosTrouchFn(className, isAdd) {
iosTrouchFnEl = document.querySelector(className);
//el需要滑动的元素
if(isAdd) {
iosTrouchFnEl.addEventListener('touchmove',function(e){
e.isSCROLL = true;
})
document.body.addEventListener('touchmove', preventSwiping, {passive: false})
} else {
document.body.removeEventListener('touchmove', preventSwiping);
}
//passive防止阻止默认事件不生效
}
function preventSwiping(e){
if(!(e as any).isSCROLL){
e.preventDefault(); //阻止默认事件(上下滑动)
}else{
//需要滑动的区域
let top = iosTrouchFnEl.scrollTop; //对象最顶端和窗口最顶端之间的距离
let scrollH = iosTrouchFnEl.scrollHeight; //含滚动内容的元素大小
let offsetH = iosTrouchFnEl.offsetHeight; //网页可见区域高
let cScroll = top + offsetH; //当前滚动的距离
//被滑动到最上方和最下方的时候
if(top == 0){
top = 1; //0~1之间的小数会被当成0
}else if(cScroll === scrollH){
iosTrouchFnEl.scrollTop = top - 0.1;
}
}
}