移动端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 相关文章推荐
javascript 密码强度验证规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
May 18 Javascript
js各种验证文本框输入格式(正则表达式)
Oct 22 Javascript
JS焦点图切换,上下翻转
May 12 Javascript
js获取某月的最后一天日期的简单实例
Jun 22 Javascript
javascript实现数字+字母验证码的简单实例
Feb 10 Javascript
javaScript使用EL表达式的几种方式
May 27 Javascript
易操作的jQuery表单提示插件
Dec 01 Javascript
JavaScript简单获取页面图片原始尺寸的方法
Jun 21 Javascript
JavaScript中的toString()和toLocaleString()方法的区别
Feb 15 Javascript
微信小程序实现图片滚动效果示例
Dec 05 Javascript
vue权限管理系统的实现代码
Jan 17 Javascript
TensorFlow.js 微信小程序插件开始支持模型缓存的方法
Feb 21 Javascript
学习使用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 MVC模式在网站架构中的实现分析
2010/03/04 PHP
PHP中__get()和__set()的用法实例详解
2013/06/04 PHP
编写安全 PHP应用程序的七个习惯深入分析
2013/06/08 PHP
ThinkPHP实现生成和校验验证码功能
2017/04/28 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
Laravel框架搜索分页功能示例
2019/02/01 PHP
如何使Chrome控制台支持多行js模式——意外发现
2013/06/13 Javascript
js中widow.open()方法使用详解
2013/07/30 Javascript
js 绑定键盘鼠标事件示例代码
2014/02/12 Javascript
javascript学习笔记整理(概述、变量、数据类型简介)
2015/10/25 Javascript
JavaScript使用DeviceOne开发实战(二) 生成调试安装包
2015/12/01 Javascript
自动完成的搜索框javascript实现
2016/02/26 Javascript
JavaScript实现时间倒计时跳转(推荐)
2016/06/28 Javascript
boostrapTable的refresh和refreshOptions区别浅析
2017/01/22 Javascript
jquery Form轻松实现文件上传
2017/05/24 jQuery
js中document.write和document.writeln的区别
2018/03/11 Javascript
javascript系统时间设置操作示例
2019/06/17 Javascript
微信小程序之 catalog 切换实现解析
2019/09/12 Javascript
python用ConfigObj读写配置文件的实现代码
2013/03/04 Python
Python中使用partial改变方法默认参数实例
2015/04/28 Python
Python的__builtin__模块中的一些要点知识
2015/05/02 Python
Python实现批量下载文件
2015/05/17 Python
详解分布式任务队列Celery使用说明
2018/11/29 Python
使用 Python 处理 JSON 格式的数据
2019/07/22 Python
python-序列解包(对可迭代元素的快速取值方法)
2019/08/24 Python
Raffaello Network西班牙:意大利拉斐尔时尚购物网
2019/03/12 全球购物
如何利用XMLHTTP检测URL及探测服务器信息
2013/11/10 面试题
公务员职务工作的自我评价
2013/11/01 职场文书
小学三八妇女节活动方案
2014/03/16 职场文书
市级优秀班主任事迹材料
2014/05/13 职场文书
自我推荐信格式模板
2015/03/24 职场文书
酒店人事主管岗位职责
2015/04/11 职场文书
单方投资意向书
2015/05/11 职场文书
民事辩护词范文
2015/05/21 职场文书
催款函范本大全
2015/06/24 职场文书
技术入股合作协议书
2016/03/21 职场文书