Firefox和Opera有一个新特性,名叫“往返缓存”(back-forward cache,或bfcache),可以在用户使用浏览器的“后退”和“前进”按钮时加快页面的转换速度。这个缓存中不仅保存着页面数据,还保存了DOM和JavaScript的状态;实际上是将整个页面都保存在了内存里。如果页面位于bfcache中,那么再次打开该页面就不会触发load事件。尽管由于内存中保存了整个页面的状态,不触发load事件也不应该会导致什么问题,但为了更形象地说明bfcache的行为,Firefox还是提供了一些新事件。

第一个事件就是pageshow,这个事件在页面显示时触发,无论页面是否来自bfcache。在重新加载页面中,pageshow会在load事件触发后触发;而对于bfcache中的页面,pageshow会在页面状态完全恢复的那一刻触发。另外要注意的是,虽然这个事件的目标是document,但必须将其事件处理程序添加到window。来看下面的例子:

var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    }
};
(function () {
    var showCount = 0;
    EventUtil.addHandler(window, "load", function () {
        alert("Load fired");
    });
    EventUtil.addHandler(window, "pageshow", function (event) {
        showCount++;
        alert("Show has been fired " + showCount + " times.");
    });
})();

这个例子使用了私有作用域,以防止变量showCount进入全局作用域。当页面首次加载完成时,showCount的值为0。此后,每当触发pageshow事件,showCount的值就会递增并通过警告框显示出来。如果你在离开包含以上代码的页面之后,又单击“后退”按钮返回该页面,就会看到showCount每次递增的值。这是因为该变量的状态,乃至整个页面的状态,都保存在了内存中,当你返回这个页面时,它们的状态得到了恢复。如果你单击了浏览器的“刷新”按钮,那么showCount的值会被重置为0,因为页面已经完全重新加载了。

除了通常的属性之外,pageshow事件的event对象还包含一个名为persisted的布尔值属性。如果页面中保存在了bfcache中,则这个属性的值为true;否则,这个属性的值为false。可以像下面这样在事件处理程序中检测这个属性:

var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    }
};
(function () {
    var showCount = 0;
    EventUtil.addHandler(window, "load", function () {
        alert("Load fired");
    });
    EventUtil.addHandler(window, "pageshow", function (event) {
        showCount++;
        alert("Show has been fired " + showCount + " times.Persisted? " + event.persisted);
    });
})();

通过检测persisted属性,就可以根据页面在bfcache中的状态来确定是否需要采取其它操作。

与pageshow事件对应的是pagehide事件,该事件会在浏览器卸载页面的时候触发,而且是在unload事件之前触发。与pageshow事件一样,pagehide在document上面触发,但其事件处理程序必须要添加到Windows对象。这个事件的event对象也包含persisted属性,不过其用途稍有不同,来看下面的例子:

var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    }
};
EventUtil.addHandler(window, "pagehide", function (event) {
    alert("Hiding. Persisted? " + event.persisted);
});

有时候,可能需要在pagehide事件触发时根据persisted的值采取不同的操作。对于pageshow事件,如果页面是从bfcache中加载的,那么persisted的值就是true;对于pagehide事件,如果页面在加载之后会保存在bfcache中,那么persisted的值也会被设置为ture。因此,当第一次触发pageshow时,persisted的值一定是false,而在第一次触发pagehide时,persisted就会变成true(除非页面不会保存在bfcache中)。

指定了onunload事件处理程序的页面会被自动排除在bfcache之外,即使事件处理程序是空的。原因在于,onunload最常用于撤销在onload中所执行的操作,而跳过onload后再次显示页面很可能会导致页面不正常。

页面显示(pageshow)和页面隐藏(pagehide)事件的更多相关文章

  1. [YII2] 展示页面显示图片 以及手机号隐藏为*和姓名隐藏姓为*,

  2. 用jquery将多个页面中相似页面显示到一个页面并实现来回跳转

    今天遇到一个问题,客户说页面来回跳转太麻烦了,需要把相似的页面做到一个页面上去. 接下来说一下记录一下解决方法. 首先这是三个页面中相似的Div: <div class="wenti& ...

  3. html在一个页面显示另一个页面的部分内容

    老板今天让在网站上面显示实时监控画面,研究了一早,找了个简单的方法 先把监控分享在网上(我使用的海康威视摄像头,分享到萤石直播http://square.ys7.com/square/index.js ...

  4. HBuilder mui 手机app开发 Android手机app开发 ios手机app开发 打开新页面 预加载页面 关闭页面

    创建子页面 在mobile app开发过程中,经常遇到卡头卡尾的页面,此时若使用局部滚动,在android手机上会出现滚动不流畅的问题: mui的解决思路是:将需要滚动的区域通过单独的webview实 ...

  5. 浏览器,tab页显示隐藏的事件监听--页面可见性

    //监听浏览器tab切换,以便在tab切换之后,页面隐藏的时候,把弹幕停止 document.addEventListener('webkitvisibilitychange', function() ...

  6. Framework7首页隐藏navbar其他页面显示navbar

    Framework7首页隐藏navbar其他页面显示navbar 帮别人解决问题,自己也记录一下, 首页.navbar加.navbar-hidden, 首页.page加.no-navbar, 如果首页 ...

  7. 设置一个div网页滚动时,使其固定在头部,当页面滚动到距离头部300px时,隐藏该div,另一个div在底部,此时显示;当页面滚动到起始位置时,头部div出现,底部div隐藏

    设置一个div网页滚动时,使其固定在头部,当页面滚动到距离头部300px时,隐藏该div,另一个div在底部,此时显示: 当页面滚动到起始位置时,头部div出现,底部div隐藏 前端代码: <! ...

  8. pageshow和pagehide事件

    Firefox和opera有一个特性,往返缓存:可以在用户使用浏览器的后退和前进按钮时加快页面的转换速度,这个缓存不仅保存了页面的数据,还有DOM和JavaScript的状态. 为了更形象的说明bfc ...

  9. js判断移动端页面按home键切换到桌面事件

    ---恢复内容开始--- 原理就是通过页面标签切换事件(visibilitychange)来判断,亦可用户移动端桌面和app切换. 先看代码: var hiddenProperty = 'hidden ...

随机推荐

  1. 资源监控工具--spotlight

    1.被监控服务器为Ubuntu server,先在服务器上创建一个用户,专门用于监控使用! 因为远程监控服务器,需要获取服务器的资源,所以必须要有权限.使用文档明确说明,不能使用root用户,但是我用 ...

  2. GPT vs MBR 分区 ,,, Legacy BIOS vs UEFI BIOS

    MBR与GPT两种磁盘分区格式的区别 http://itoedr.blog.163.com/blog/static/120284297201378114053240 GPT Partition Tab ...

  3. 发现一php木马代码

    <?php ;//无需验证密码! $shellname='hello~地球~猴子星球欢迎你 '; define('myaddress',__FILE__); error_reporting(E_ ...

  4. BZOJ1004 [HNOI2008]Cards(Polya计数)

    枚举每个置换,求在每个置换下着色不变的方法数,先求出每个循环的大小,再动态规划求得使用给定的颜色时对应的方法数. dp[i][j][k]表示处理到当前圈时R,B,G使用量为i,j,k时的方法数,背包思 ...

  5. ARM伪指令,王明学learn

    ARM伪指令 在ARM汇编语言程序中里,有一些特殊指令助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作.伪指令在元程序中的作用是为完成汇编 ...

  6. 使用postMesssage()实现跨域iframe页面间的信息传递----转载

    由于web同源策略的限制,当页面使用跨域iframe链接时,主页面与子页面是无法交互的,这对页面间的信息传递造成了不小的麻烦,经过一系列的尝试,最后我发现有以下方法可以实现: 1. 子页面url传参 ...

  7. 【jQuery 区别】attr()和prop()的区别

    1>>> 今天实现一个 点击更新按钮 ,可以勾选上本行的的checkbox的功能: 使用代码: /** * updateproduct.htmls 更新 产品信息 */ $(docu ...

  8. hdu 1251 字典树的应用

    这道题看了大神的模板,直接用字典树提交的会爆内存,用stl 里的map有简单有快 #include <iostream> #include <map> #include < ...

  9. JS获得鼠标位置

    <body> <script> function mouseMove(ev) { ev = ev || window.event; var mousePos = mouseCo ...

  10. 《DSP using MATLAB》示例Example4.13

    代码: b = [1, 0, -1]; a = [1, 0, -0.81]; % [R, p, C] = residuez(b,a); Mp = (abs(p))' Ap = (angle(p))'/ ...