众所周知:ajax可以实现页面的局部刷新,可以做到非常奈斯的数据加载效果,给用户带来非常良好的体验,但是ajax的除了会曝露一些不太安全的服务器信息之外,最蛋疼的就是不能在
浏览器的历史会话中保留记录。就是当你点开一个页面,ajax各种数据加载各种欢乐啊,例如一个列表页面,异步加载来翻页。结果用户一不小心刷新了页面,那么页码就得重新开始计算,一旦用户改变了会话状态(浏览器的前进、后退、刷新),那么ajax就会丢失相关的数据。
最近在网上浏览各大网站无意中发现了ajax异步刷新但是地址栏改变的效果。
优点如下:
卓越的用户体验
对搜索引擎更加友好
更多敬请补充...
实现方案(写入会话状态):
对这种效果抱着好奇的心态就去查阅了一下资料。
在Html5中为window.history对象引入了pushState和replaceState方法,对window.history对象还不太了解的童鞋请自行查阅相关资料。
示例:
复制代码
//格式约定
history.pushState(data, title[, url]);
///
/// pushState方法调用示例,replaceState方法同样的参数格式,
///
本方法负责将自定义数据写入浏览器会话历史
///
linkFly原创,引用请注明出处,谢谢
///
///
/// 需要进行保存(在历史会话)的数据,该数据可以在下一次会话中读取出来
///
///
/// 写入历史会话的标题,经过测试暂时没有发现用处,不会对当前文档标题产生影响,可以传入空字符串
///
///
/// 要写入浏览器历史会话的Url【注意不允许跨域】
///
///
window.history.pushState(
{pageIndex:1,keywords:'善了个哉'},
document.title,
window.location.pathname+' pageIndex=1'
);
复制代码
原理:
该方法隶属Html5,是为了解决ajax方法不能“回到过去”的问题。window.history负责管理浏览器会话历史,而pushState则在浏览器历史中添加一条会话历史(replaceState则是替换一条历史)作为当前会话状态,而在用户刷新了页面之后进入这条会话,这时候我们只需要把会话的数据读取出来就行了。
对每个参数进行特别说明一下:
Data:可以任意存放一组数据,这组数据存放在该历史对话中,下次进入该对话则可以通过读取该数据来进行状态保持,例如可以存放页码信息,但是注意值不能引用对象,会报ObjectCloneError(对象克隆异常),例如当前页面的Element、$("#testId")这种引用了依赖当前页面的数据,Data数据要保持独立,值不允许为引用类型的对象。
Title:参阅的大部分文档对其都没有说明,只是简单的描述了文档标题。应该是在读取会话数据的时候自动对应到页面标题上,但是经过测试并不会对页面标题有任何的影响,如果是为了实现自动对应标题的话,功能就有点鸡肋(完全可以用Data),一般可以传入:document.title或''(空字符串)
Url:就是要写入历史会话的url,假定我们已经在历史记录中写入了Url,浏览器进行前进操作,跳转到了别的页面,然后再返回,进入的就是这个url。不允许跨域!本着面向对象的思想,一般可以通过window.location.pathname获取当前url地址,然后通过字符串拼接后面的参数传入就可以生成稳妥的url了。
读取会话历史:
在轻松写入了会话历史之后,我们还需要将它读出来才行。这个读取的切入点,嗯,查阅了资料说的都是通过onpopstate事件,实际上在这个事件上非常的蛋疼,我查阅的多数的文章都告诉说捕捉这个事件即可,代码如下:
本示例不推荐使用:
复制代码
//本代码仅作参考
//环境 Firefox 25.0.1级以下版本不推荐使用本代码(高版本尚未测试)
window.addEventListener('popstate', function(e) {
///
///
在页面初始化加载完成中添加该事件,则可以监听到onpopstate事件,而浏览器进行前进、后退、刷新操作都会触发本事件
///
linkFly原创,引用请注明出处,谢谢
/// ///
if (e.state) {
//e.state就是pushState中保存的Data,我们只需要将相应的数据读取下来即可
}
});
// 传闻可以直接使用history.state来获取当前对应的state数据,笔者尚未测试,有兴趣的可以自行研究下,注意主要测试Firefox
复制代码
注意,以上代码在Firefox下存在问题。
在这些资料中都只是草草的告诉说onpopstate事件可以做到读取数据,但在Firefox下,页面加载中根本不会触发onpopstate事件。
参考:MDN Window.onpopstate事件文档
大家注意中间一大段的最后一句:
Chrome and Safari always emit a popstate event on page load, but Firefox doesn't.
翻译过来就是Chrome和Safari都会在页面加载中触发该事件,但是Firefox不会。
所以这时候有两种处理方案:
在页面加载中手动触发该事件
通过解析url来实现,注意如果希望通过url来获取数据的话,那么之前是pushState主要需要保存的数据并非是data,而是url。这个概念需要清晰。
在页面加载中手动触发该事件代码如下:
$(function(){
//通过jQuery.trigger()方法触发
//或者自己手写js触发,具体代码这里就不贴了...
$(window).trigger("hashchange");
});
通过解析url代码如下:
复制代码
function getUrlParameter(fieldName) {
///
/// 1: 获取地址栏参数方法
///
- getUrlParameter(fieldName) - 在当前Url中查询指定的参数,返回查询得到的值,当不支持pushState或没有查询到参数的时候返回空字符串
///
///
/// 要查询的字符串
///
///