这次迭代我们做一个 “老带新” 的活动页,总共分为 活动主页、分享登记页、邀请记录页、分享海报页。
我本人就使用了当前流行的vue框架开发,并且加入了前端路由,个人觉得单页用起来特别爽,这也为后面踩坑埋下了伏笔[捂脸哭]。
1、滚动穿透。
image.png
如上图,我有一个弹窗,然后弹窗里边是可以滚动的,可是当我滑动我的弹窗内容的时候,发现遮罩下面的页面也跟着滑动了,这就是经典的滚动穿透,好在同事在做别的功能的时候做了这个坑的处理,代码如下:
export function setHtmlScroll(v, flag) {
if(flag) {
v.curPos = document.documentElement.scrollTop || document.body.scrollTop;
document.querySelector('html').style.position = 'fixed';
document.querySelector('html').style.top = -v.curPos + 'px';
}
if(!flag) {
document.querySelector('html').style.position = 'static';
document.querySelector('html').style.top = 'auto';
window.scrollTo(0, v.curPos);
}
}
我把这个方法作为公共方法放在utils.js中,调用的时候,先引入:
import { setHtmlScroll } from "../js/utils.js";
data() {
return {
curPos: 0
}
}
然后在打开弹窗的时候调用:
setHtmlScroll(this, true);
在关闭弹窗的时候调用:
setHtmlScroll(this, false);
这样就能完美解决这个滚动穿透的问题了。不过我一开始使用没有成功,就是设置
document.querySelector('html').style.position = 'fixed';
并没能使底部的页面固定下来,仍然可以滑动,然后在我仔细地查找了我的dom结构以及style的时候发现,原来我的html和body都给了:height: 100%; 这就很尴尬了,去掉了之后就OK了,虚惊一场。
然而接下来我又发现,因为是单页路由嘛,所以html节点共用。就会造成以下场景:
从主页进入邀请页,再返回主页,在主页打开弹窗,再前往邀请页,发现邀请页滑动不了了。
想必有经验的朋友都知道是怎么回事了,没错,html节点共用,在主页弹窗打开的时候我设置了html的position为fixed,所以邀请页也会被固定住啦。
解决的方法也简单:在主页destroyed的时候放开html节点。
destroyed() {
setHtmlScroll(this, false);
}
2、页面缓存
如图,我需要做一个缓存,避免输入框的值被丢失:
image.png
页面缓存也很简单:
image.png
现在路由中加入keepAlive为true,然后主入口文件路由使用:
image.png
然而加了缓存之后,又遇到了类似上面的场景。因为这个页面也有一个【活动规则】的打开弹窗,还有【用户协议】和【隐私协议】两个路由。
image.png
所以也会遇到
从这个页面【记为分享登记页】访问【用户协议】,再返回【分享登记页】,然后打开【活动规则】弹窗,此时html固定,然后再前网【用户协议】,用户协议滑动不了。
所以我又用了
destroyed() {
setHtmlScroll(this, false);
}
然而,解决了【用户协议】无法滑动的问题,却又产生了新的问题。由于【记为分享登记页】是做了缓存的,所以退回是不会刷新的,此时页面上的【活动规则】弹窗仍然打开,而html的position被改为了static,滚动穿透又出现了,解决方法就是利用缓存页面的一个钩子,激活缓存页面钩子:activated。
activated() {
setHtmlScroll(this, true);
}
不过需要先判断是否打开了弹窗,打开弹窗了才设置setHtmlScroll(this, true);
。
到此为止,关于单页的滚动穿透所带来的一系列的问题才就完全解决了。
网友评论