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

而对于浏览器来说,大部分浏览器的返回是直接使用缓存的,不会执行任何的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>

这个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里面内容的重新加载,会有一个时间间隙。

另外还有两种方法监听页面离开返回:

this.pushHistory();
       window.addEventListener("popstate", function(e) {
           //do something
            console.log("我监听到页面离开了")
        },false);
    pushHistory: function() { //改方法添加了一个历史记录,路径为#,保证了不刷新页面,不直接后退。
        var state = {
            title: "title",
            url: "#"
        window.history.pushState(state, "title", "#");

参考知识点:History详解

https://developer.mozilla.org/zh-CN/docs/Web/API/History_API

document.addEventListener("visibilitychange", function() {
  console.log( document.hidden );
  // 逻辑处理

Document.hidden (只读属性)返回布尔值,表示页面是(true)否(false)隐藏。

参考链接:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/hidden

项目中的需求:点击浏览器中的返回按钮,要让页面重新加载资源。因为这部分的资源每次去加载的内容都不一样,如果返回的时候,还是看到原先的内容,那做这个内容块的意义就很小了;而如果用户看完了这部分内容,再返回来的时候,这个地方换成了新的内容,这样就能体现这部分的价值了。而对于浏览器来说,大部分浏览器的返回是直接使用缓存的,不会执行任何的javascript代码。原因:部分浏览器在后退时不会触发onl...
项目中的需求: 点击浏览器中的返回按钮,要让页面重新加载资源。因为这部分的资源每次去加载的内容都不一样,如果返回的时候,还是看到原先的内容,那做这个内容块的意义就很小了;而如果用户看完了这部分内容,再返回来的时候,这个地方换成了新的内容,这样就能体现这部分的价值了。 而对于浏览器来说,大部分浏览器的返回是直接使用缓存的,不会执行任何的javascript代码。原因:部分浏览器在后退时不会触发onload事件,這是HTML5世代浏览器新增的特性之一——Back-Forward Cache(简称bfcache) 什么是bfcache? bfcache,即back-forward cache,可称为
//e.persisted判断是否后退进入,从缓存冲获取时为true否则为false window.addEventListener('pageshow', () => { if (e.persisted || (window.performance && window.performance.navigation.type == 2)) { location.reload() }, false)
返回页面不刷新,一些失效的信息依然显示在页面上。这个问题在iphone手机上会出现,在Android手机上返回时会自动刷新(由于手机机器种类不多,无法做更多测试,欢迎补充)。 为了解决这个问题实验了很多解决办法用计时器呀onload呀都不行,后来找到了一个方法pageshow。 onpageshow 事件在用户浏览网页时触发。 onpageshow 事件类似于 onload 事件,onload 事件在页面第一次加载时触发, onpageshow 事件在每次加载页面时触发,即 onload 事件在页面
公司的一个小项目,把h5小游戏页面嵌入到app里面,但是返回键和分享按钮并不是我们写的,所以我们得监测用户点击手机返回键按钮,跳出一个是否确定退出的弹窗,我也百度了很多次,但是都会有点问题,最后找到了一个方法。 pushHistory(); window.addEventListener("popstate", function(e) { alert("我监听到了浏览器的返回按钮事件啦");//在这里写你监听后需要做的事情 }, false); function pushHistory() {
项目中的需求:点击浏览器中的返回按钮,要让页面重新加载资源。因为这部分的资源每次去加载的内容都不一样,如果返回的时候,还是看到原先的内容,那做这个内容块的意义就很小了;而如果用户看完了这部分内容,再返回来的时候,这个地方换成了新的内容,这样就能体现这部分的价值了。 而对于浏览器来说,大部分浏览器的返回是直接使用缓存的,不会执行任何的javascript代码。原因:部分浏览器在后退时不会触发onl...
  history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。由于安全方面的考虑,开发人员无法得到用户浏览器的URL,但借由用户访问过的页面列表,可以在不知道实际URL的情况下实现后退和前进。本文将详细介绍BOM中的history对象 length   history.length属性保存着历史记录的URL数量。初始时,该值为1。如果当前窗口先后访问了三个网址,h...
  大家是否经常遇到在关闭网页的时候,会看到一个确定是否离开当前页面的提示框?想一些在线测试系统、信息录入系统等就经常会有这一些提示,避免用户有意或者无意中关掉了页面,导致数据丢失。这里面的实现过程很简单,利用了HTML DOM事件中的onunload和onbeforeunload方法。 unload 事件属性   定义:当用户卸载文档时执行一段 JavaScript,例如:
  事发背景(时间较久):   在一个阳光明媚的一天,这天lz正在工位上悠闲的敲着代码;说时迟那时快,运营小姐姐箭步过来,让lz做一个挽留弹窗;我当时一听这TM不是流氓么。于是便有了以下的故事。。。   如何实现:   众所周知,我们一般是无法去监听浏览器的返回事件的;更别说是用户设备的物理返回键了;依稀记得浏览器确实是有个关闭事件----onbeforeunload;但是这个原意...
1rem为何不能为1px 当前浏览器设定的最小字体大小为12px,所以浏览器自动把html{font-size: 1px} 识别为html{font-size: 12px},所以效果也就是1rem = 12px。 在调整浏览器最小字体大小以后,也验证了以上原因是正确的。 所以设定为1rem=100px,也是最简便的开发方式。 宽度需要使用百分比 例如这样: window.addEventListener("popstate", function(e) { //do something console.log("我监听页面离开了") },false); ```html <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> 另外,你也可以使用 CSS3 的媒体查询来适配不同的屏幕尺寸,例如: ```css @media screen and (max-width: 768px) { /* 在屏幕宽度小于等于 768px 时应用的样式 */