`
IT_hack
  • 浏览: 15683 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

页面显示(pageshow)和页面隐藏(pagehide)事件

阅读更多
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后再次显示页面很可能会导致页面不正常。
分享到:
评论

相关推荐

    在vue项目中利用popstate处理页面返回的操作介绍

    一个标题(现在被忽略了),以及一个可选的URL地址), 注意:IOS版的微信,是会立即触发popstate事件,所以需要pageshow做下处理,(当一条会话历史记录被执行的时候将会触发页面显示(pageshow)事件。(这包括了后退...

    pageshow.jsp

    pageshow.jsp

    page-visibility:页面可见性API包装器和Polyfill

    page-visibility.js 包装器这个小包装器隐藏了供应商前缀,并为浏览器中的可见性API提供了有用的高级API...本机支持iOS Safari 7.x-本机支持无法正常工作,并充斥着pageshow / pagehide事件iOS Safari 8.0+-本机支持And

    微信小程序页面缩放式侧滑效果的实现代码

    先给大家展示下效果图,大家感觉不错,请参考实现代码: ...<view class='page {{isFix?pageShow:pageHide}}'> <view class='h-toggle iconfont icon-list' bindtap='pageBtn'></view> <view cla

    解决ios微信页面回退不刷新的问题

    window.addEventListener('pageshow', function () { if (isPageHide) { [removed].reload(); } }); window.addEventListener('pagehide', function () { isPageHide = true; }); }) 以上这篇解决ios微信...

    when:在事件触发之前或之后订阅事件

    什么时候-在事件触发之前或之后订阅事件 特征 没有依赖 小于500 B缩小+压缩 全类型(TypeScript) CDN构建(UMD) -jsDelivr , unpkg 安装 $ npm install @chocolatey/when 概要 import when from '@chocolatey...

    ios微信浏览器返回不刷新问题完美解决方法

    开始用的表单提交,返回参数就丢失,换成url跳转,popstate监听 (注释部分)ios10测试始终有问题,继续搜,最后用pageshow,pagehide完美解决(另外说一句:珍爱生命,远离微信和ios) var wxback = { init :...

    思维网络PHP万能分页类 1.3

    ... //引入分页类 ... //显示分页条 其中 $px->pageshow('default'); default 是默认样式 自带三种样式  可选: default (默认) wap(手机网站分页样式) style(可以自定义CSS样式的分页样式);

    最强大的JAVA分页类

    PageShow: private Page 实体类 Method: private void page(); 给 Page 中的 param pageCount (总页数) 赋值 public List showPage(int pageSize,int page,ArrayList<Object> list) 得到当前分页的内容...

    Gridview实例

    this is a Gridview example, and complete the following: Data Bind, Insert, Update, Delete, PageShow, and sort by items and so on, may you use happy!

    Python 使用 PyQt5 开发的关机小工具分享

    前两天简单认识了一下PyQt5,... def pageShow(self,page): #设置窗口的位置和大小 page.setGeometry(400,400,400,200) #设置窗口的标题 page.setWindowTitle('Window shutdown') #设置窗口的图标 #page.setWind

    rem-responsive-layout:用于移动设备的“rem”响应式布局的代码片段,计算屏幕宽度并使用字体大小进行响应

    响应式布局 用于移动设备的rem响应式布局的代码片段,计算屏幕宽度并使用字体大小进行响应 ... ps = 'pageshow'; d[on]('DOMContentLoaded', resizeFontSize); if ('on' + ps in w) w[on](ps, function(e)

Global site tag (gtag.js) - Google Analytics