H5页面在IOS微信中跳转时,会出现底部工具栏,遮挡页面底部内容

Posted 地瓜哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了H5页面在IOS微信中跳转时,会出现底部工具栏,遮挡页面底部内容相关的知识,希望对你有一定的参考价值。

问题描述:
ios微信中打开H5页面,当浏览器内出现跳转产生url历史记录时,页面底部会出现一个带有前进和后退按钮的工具栏,会遮挡页面底部的内容。

分析原因:
页面跳转时,微信浏览器通过window.history读取到浏览的历史记录,此时便会在页面底部显示出前进后退按钮的工具栏,造成页面底部内容遮挡。但刷新一下该页面,就不会遮挡了。底部的工具栏是在页面完成渲染之后才渲染的。

解决方案:

不产生历史记录让底部工具栏不出现

由于未授权代码无法清除会话历史(session History),也不能禁用回退/前进功能。最快捷的可用方式是使location.replace()方法,提供指定的URL来替换当前的会话历史(session history)。

  1. 用replace替代push指第一个页面到第二个页面push->replace,其他页面不变。

    实际应有中IOS跳转应用商店使用的是中间页和tencent/camp-launch-app的插件,使用的是window.location.href = url跳转,未采用。
    
  2. 在第一个界面产生历史记录:可以在跳转到第一个页面前再加一个页面,此页面不需要内容直接跳转即可。

    在实际应用中在第一个页面产生历史记录不是最优解决方案,未采用。
    
  3. 在页面加载之前通过主动添加空的历史记录,触发浏览器的history监听机制,让浏览器先于页面调出底部工具栏,从而解决遮挡问题。

    在路由守卫中增加对 window.history 的处理:
    
router.beforeEach((to, from, next) => {
    window.history.replaceState(null, null, window.location.href);
    next();
});

replaceState 是替换浏览历史中的上一条记录,用当前页面的地址替换上一条记录,本质上浏览历史是不变的。
经测试仅IOS 6 Plus生效。

原因:IOS微信中调整到下一页面后并未将上一页面修改的url保持在历史记录中。
eg: 返回上一页并未返回到 http://www.a.com?time=xxx,而... http://www.a.com 中。

底部工具栏出现后,再获取页面高度或重新定位

IOS底部导航栏出现会导致页面高度改变,可以利用onresize监听页面大小变化,在高度改变后重新设置非正常布局流元素即可解决。

function resizeHeight(e, delay = 200){ // delay = 200ms仅供参考,若还出现问题可增加时间延迟
    let resizeTimeout;
    if (!resizeTimeout) {
        resizeTimeout = setTimeout(function() {
            resizeTimeout = null;
            let navBar = document.getElementsByClassName("component-tab-bar-box")[0]; //此类即为非正常布局流元素
            let bottom = navBar.style.bottom;
            navBar.style.bottom = parseInt(bottom) ? 0 : 1 + \'px\';
        }, delay);
    }
}
window.onresize = resizeHeight;

但delay时间不好确定,未采用。

在IOS微信中通过pageshow事件决定是否需要刷新页面

H5页面在IOS微信内置浏览器中点击返回按钮返回上一页时,上一页面不会被刷新。在浏览器缓存机制中,在返回上一页的操作中, html/js/css/接口等动静态资源不会重新请求,但是js会重新加载。但在IOS微信页面中js也会保存上一页面最后执行的状态,不会重新执行js。

浏览器前进/后退缓存(Backward/Forward Cache,简称BF Cache)是一种浏览器优化,HTML标准并未指定其如何进行缓存,因此缓存行为是各浏览器实现不尽相同。

pageshow:当一条会话历史记录被执行的时候将会触发页面显示(pageshow)事件。(这包括了后退/前进按钮操作,同时也会在onload 事件触发后初始化页面时触发)。

window.addEventListener(\'pageshow\', function(event) {
    // event.persisted: Boolean类型,表示网页是否是来自缓存。
});

pageshow兼容性:

FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support41.5 (1.8)11155
FeatureandroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support2.3?11355.1

performance.navigation的type值为2,页面通过历史记录和前进后退访问时。
即:window.performance.navigation.type === 2

performance.navigation兼容性:

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Basic support101279158
FeatureWebView AndroidChrome AndroidFirefox for AndroidOpera AndroidSafari on iosSamsung Internet
Basic support<= 37187No91.0
if (isWxH5 && Utils.isIos()) {
    window.onpageshow = function(e) {
        if(e.persisted || (window.performance && window.performance.navigation.type == 2)) {
            window.location.reload()
        }
    }
}

pageShow事件在页面显示即会触发,无论页面是否来自BF Cache。通过检测persisted属性即可判断是否存在 BF Cache 行为。IOS中的微信页面,支持pageShow方法、persisted属性以及performance.navigation属性。

参考文章:

  1. IOS微信下问题1 底部导航栏导致标签位置偏移
  2. iOS新版微信底部工具栏遮挡问题完美解决
  3. Ios中微信页面返回上一页去除缓存几种常见思路
  4. iOS设备 微信h5页面回退 内容不刷新的问题
  5. iOS微信底部返回横条问题
  6. h5返回到上一页ios手机页面不刷新
  7. 微信页面入口文件被缓存解决方案

以上是关于H5页面在IOS微信中跳转时,会出现底部工具栏,遮挡页面底部内容的主要内容,如果未能解决你的问题,请参考以下文章

微信h5页面中跳转外部浏览器下载APK的办法

从微信中跳到外部浏览器

怎样微信扫描二维码跳转页面,H5页面在微信中下载APP的实现方式

微信中怎样嵌入自己开发的h5页面

如何从微信浏览器中跳转到APP指定页面?

vueh5兼容safari底部遮罩问题