微信公众号开发vue单页路由踩坑记 - 滚动穿透

2019-04-12  本文已影响0人  你若像风

这次迭代我们做一个 “老带新” 的活动页,总共分为 活动主页、分享登记页、邀请记录页、分享海报页。
我本人就使用了当前流行的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);
到此为止,关于单页的滚动穿透所带来的一系列的问题才就完全解决了。

上一篇下一篇

猜你喜欢

热点阅读