移动端H5页面返回并刷新页面(BFcache)的方法


Posted in Javascript onNovember 06, 2018

项目中的需求:

点击浏览器中的返回按钮,要让页面重新加载资源。因为这部分的资源每次去加载的内容都不一样,如果返回的时候,还是看到原先的内容,那做这个内容块的意义就很小了;而如果用户看完了这部分内容,再返回来的时候,这个地方换成了新的内容,这样就能体现这部分的价值了。

而对于浏览器来说,大部分浏览器的返回是直接使用缓存的,不会执行任何的javascript代码。原因:部分浏览器在后退时不会触发onload事件,?是HTML5世代浏览器新增的特性之一——Back-Forward Cache(简称bfcache)

什么是bfcache?

bfcache,即back-forward cache,可称为“往返缓存”,可以在用户使用浏览器的“后退”和“前进”按钮时加快页面的转换速度。这个缓存不仅保存页面数据,还保存了DOM和JS的状态,实际上是将整个页面都保存在内存里。如果页面位于bfcache中,那么再次打开该页面就不会触发onload事件

pageshow事件

这个事件在用户浏览网页时触发,pageshow 事件类似于 onload 事件,onload 事件在页面第一次加载时触发, pageshow 事件在每次加载页面时触发,即 onload 事件在页面从浏览器缓存中读取时不触发。

pagehide事件

该事件会在用户离开网页时触发。离开网页有多种方式。如点击一个链接,刷新页面,提交表单,关闭浏览器等。pagehide 事件有时可以替代 unload事件,但 unload 事件触发后无法缓存页面。

persisted属性

pageshow事件和pagehide事件的event对象还包含一个名为persisted的布尔值属性。

对于pageshow事件,如果页面是从bfcache中加载的,则这个属性的值为true;否则,这个属性的值为false。

对于pagehide事件,如果页面在卸载之后被保存在bfcache中,则这个属性的值为true;否则,这个属性的值为false。

不同的浏览器在对当前窗口‘打开'历史记录中的前一个页面的表现上并不统一,这和浏览器的实现以及页面本身的设置有关系。

解决方案:

javascript监听pageshow事件阻止页面进入bfcache

window.addEventListener('pageshow', function (e) {
if (e.persisted) {
window.location.reload()
}
})

在uc和微信中测试通过,但是在某些安卓手机自带的浏览器中无效。

javascript监听pagehide事件阻止页面进入bfcache

window.addEventListener('pagehide', function (e) {
 var dom = document.body;
 dom.children.remove();
 setTimeout(function () {
  dom.appendChild("<script type='text/javascript'>window.location.reload();<\/script>");
 });
});

设置meta标签,清除页面缓存

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如下

  • Public指示响应可被任何缓存区缓存
  • Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效
  • no-cache指示请求或响应消息不能缓存
  • no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
  • max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应
  • min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应
  • max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

注:有些情况下设置清除缓存也没有起到作用,我自己做的这个h5页面就没有起到效果。具体情况还是要具体分析。

我遇到的情况:

<div class="content">
<iframe id="iframe" src="https://cpu.baidu.com/xx/xx/xxx" frameborder="no" scrolling="no"></iframe>
</div>

这个iframe中的地址每次刷新页面都会有不同的内容推送给用户。进入iframe中的内容之后,按返回按钮返回来想进行页面自动刷新,为的就是让用户看到新的内容。

做法:

使用pageshow进行整个页面刷新

window.addEventListener('pageshow', function (e) {
if (e.persisted) {
window.location.reload()
}
})

这样可以实现。

后面又觉得不妥,没有因为这个小部分而进行整个页面刷新,想到了另一种思路:因为这个iframe中的内容是动态的,可以对其进行定时器设置,如下:

let iframe = document.getElementById('iframe')
setInterval(() => {
iframe.setAttribute("src", "https://cpu.baidu.com/xx/xx/xx");
},15000)

这样也可以实现自己的功能。

最后可以结合一下:

let iframe = document.getElementById('iframe')
window.addEventListener('pageshow', function (e) {
 if (e.persisted) {
  iframe.setAttribute("src", "https://cpu.baidu.com/xx/xx/xx");
 }
})

这样做也有好处,可以避免使用定时器,对网页的性能也是比较好。但是这个方法在返回的时候,可以看到iframe里面内容的重新加载,会有一个时间间隙。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
JQuery团队打造的javascript单元测试工具QUnit介绍
Feb 26 Javascript
jQuery实现“扫码阅读”功能
Jan 21 Javascript
详解JavaScript表单验证(E-mail 验证)
Mar 31 Javascript
基于Vue实现支持按周切换的日历
Sep 24 Javascript
关于JavaScript的单双引号嵌套问题
Aug 20 Javascript
JavaScript中重名的函数与对象示例详析
Sep 28 Javascript
JS实现的邮箱提示补全效果示例
Jan 30 Javascript
vue 刷新之后 嵌套路由不变 重新渲染页面的方法
Sep 13 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
May 10 Javascript
js实现秒表计时器
Dec 16 Javascript
JavaScript中交换值的10种方法总结
Aug 18 Javascript
vue ref如何获取子组件属性值
Mar 31 Vue.js
学习使用ExpressJS 4.0中的新Router的用法
Nov 06 #Javascript
vue项目上传Github预览的实现示例
Nov 06 #Javascript
React Component存在的几种形式详解
Nov 06 #Javascript
支付宝小程序tabbar底部导航
Nov 06 #Javascript
利用JavaScript缓存远程窃取Wi-Fi密码的思路详解
Nov 05 #Javascript
利用hasOwnProperty给数组去重的面试题分享
Nov 05 #Javascript
微信小程序实现底部导航
Nov 05 #Javascript
You might like
php实现简单洗牌算法
2013/06/18 PHP
CodeIgniter基本配置详细介绍
2013/11/12 PHP
php基于单例模式封装mysql类完整实例
2016/10/18 PHP
yii2.0整合阿里云oss删除单个文件的方法
2017/09/19 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
2018/06/16 PHP
Gambit vs ForZe BO3 第二场 2.13
2021/03/10 DOTA
Mootools 1.2教程 选项卡效果(Tabs)
2009/09/15 Javascript
有关于JS构造函数的重载和工厂方法
2013/04/07 Javascript
javascript实现div浮动在网页最顶上并带关闭按钮效果实例
2013/08/13 Javascript
javascript中文本框中输入法切换的问题
2013/12/10 Javascript
jquery中filter方法用法实例分析
2015/02/06 Javascript
Bootstrap所支持的表单控件实例详解
2016/05/16 Javascript
详解nodejs的express如何自动生成项目框架
2017/07/12 NodeJs
JavaScript实现QQ列表展开收缩扩展功能
2017/10/30 Javascript
vue 实现全选全不选的示例代码
2018/03/29 Javascript
JavaScript字符串转数字的5种方法及遇到的坑
2018/07/16 Javascript
elementUI Vue 单个按钮显示和隐藏的变换功能(两种方法)
2018/09/04 Javascript
JavaScript创建对象的四种常用模式实例分析
2019/01/11 Javascript
Net微信网页开发 使用微信JS-SDK获取当前地理位置过程详解
2019/08/26 Javascript
用Python进行行为驱动开发的入门教程
2015/04/23 Python
Python常见异常分类与处理方法
2017/06/04 Python
使用matplotlib画散点图的方法
2018/05/25 Python
Python返回数组/List长度的实例
2018/06/23 Python
完美解决在oj中Python的循环输入问题
2018/06/25 Python
Python编程深度学习绘图库之matplotlib
2018/12/28 Python
Python 获取项目根路径的代码
2019/09/27 Python
django实现支付宝支付实例讲解
2019/10/17 Python
python实现将一维列表转换为多维列表(numpy+reshape)
2019/11/29 Python
python3中sorted函数里cmp参数改变详解
2020/03/12 Python
基于opencv的selenium滑动验证码的实现
2020/07/24 Python
美国女性服饰销售网站:Nasty Gal(坏女孩)
2016/07/26 全球购物
美国益智玩具购物网站:Fat Brain Toys
2017/11/03 全球购物
创业计划书的内容步骤和要领
2014/01/04 职场文书
莫言诺贝尔获奖演讲稿
2014/05/21 职场文书
SpringBoot整合RabbitMQ的5种模式实战
2021/08/02 Java/Android
根德5570型九灯四波段立体声收音机是电子管收音机的楷模 ? 再论5570
2022/04/05 无线电