现在有越来越多的需求,需要在一个复杂页面(有很多ajax异步操作,使用 js 来控制页面的展示)实现导航,书签之类的功能,同时支持浏览器向前向后浏览。由于兼容性问题,目前有三种实现的方案。这里作一下简要记录:
1. pushState
html5 提供了新的 history api,可以让开发者动态修改浏览器的url,而不会引起整个页面的重绘,给用户带来更好的体验,api 定义如下:
window.history.pushState( data, title [, url ] )
Pushes the given data onto the session history, with the given title, and, if provided and not null, the given URL.
一个简单的监听方法如下所示:
可以参考一些更详细的说明:
2. hashchange 事件
当浏览器不支持pushState特性的时候,可以使用 hashchange事件(IE67得使用第三种方式),即当hash改变的时候,浏览器会自行回调,跟pushState其实原理比较像,
一个简单的编写模式如下:
在事件回调中可以根据 location.hash 拿到最新的hash值,从而执行页面的局部刷新。
在前面,我们使用 pushState来修改当前页面url,而使用 hashchange事件的时候,
可以直接修改 location.hash 来达到触发 hashchange事件。
另外,当首次进入页面的时候,这时候,不管链接有没有hash,都不会触发 hashchange事件,
所以页面要实现初始化操作,根据初始hash值作相应的初始化。
可以参考一些更详细的说明:
3. polling(轮循) ie6 和 ie7不支持 hashchange事件,通常采用的办法是使用一个隐藏的 iframe,然后通过一个定时器不断去检测iframe的hash是否跟浏览器的一致,如果不一致,则执行回调来实现。当想要修改hash的时候,可以直接修改 location.hash,因为定时器会自行去比较,然后刷新 iframe的hash.
至于为什么要使用 iframe,那是因为直接修改location的hash值之后,ie不会新增history记录,也就不支持后退操作,而刷新iframe可以增加history记录。针对ie这种顽固的浏览器,总是让人伤神。
4. 后话
可以参考 backbone.js 中 Router和History的实现,已经兼容了这三种情况,细节比较多,有兴趣的朋友可以看看。
================================备注================================================
hashchange是老API, 浏览器支持度高, 本来是用来监听hash变化的, 可以被利用来做客户端前进后退, 但应该不是这个API的存在的主要目的.
而popstate, 及相关api, pushState等属于HTML5新标准, 产生的目的就是做客户端前进后退的, 不仅可以支持hash, 非hash的同源url也支持.
所以一般用法是浏览器支持就用popstate, 不支持再降级使用hashchange, 可参考:
操纵浏览器的历史记录
而popstate, 及相关api, pushState等属于HTML5新标准, 产生的目的就是做客户端前进后退的, 不仅可以支持hash, 非hash的同源url也支持.
所以一般用法是浏览器支持就用popstate, 不支持再降级使用hashchange, 可参考:
操纵浏览器的历史记录
================================判断页面是否读取了缓存====================================================
window.οnpageshοw=function(e){ var a=e||window.event; alert(a.persisted); if(a.persisted){ //alert("页面读取了缓存") } }