版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://cloud.tencent.com/developer/article/1347567
ajax是一个非常好玩的小东西,不过用起来也会存在一些问题。 我们可以利用ajax进行无刷新改变文档内容,但是没办法去修改URL,即无法实现浏览器的前进与后退、书签的收藏功能。
hash就是uri中#及后面的部分,例如:www.google.com.hk#123的#123。当只有hash部分发生变化时,浏览器的历史记录会产生记录,但不会向服务器发出请求,这时按后退键地址栏的uri会变化但页面内容不变。
通过window.onhashchange事件来监听hash值的更改。
ie6、7均不支持onhashchange,但可以用setInterval定期检查hash的改变,或者onload中检查的方法
曾今经典场景:Gmail借助ifram和hash实现前进和后退功能
而这样的方式对搜索引擎是十分不友好的,twitter和google约定使用hash bang (#!xxx),也就是hash后面的第一个字符为感叹号,这样的网址他们是会爬取的,但是其他搜索引擎不支持。
在HTML4,Histroy对象有下面属性方法:
在HTML5中,新增了两个方法和一个事件:
pushState
history.pushState(stateObject, title, url),包括三个参数。
pushState函数向浏览器的历史堆栈压入一个url为设定值的记录,并改变历史堆栈的当前指针至栈顶。
replaceState
该接口与pushState参数相同,含义也相同。唯一的区别在于replaceState是替换浏览器历史堆栈的当前历史记录为设定的url。需要注意的是,replaceState**不会改动**浏览器历史堆栈的当前指针。
onpopstate
该事件是window的属性。该事件会在调用浏览器的前进、后退以及执行history.forward、history.back、和history.go触发,因为这些操作有一个共性,即修改了历史堆栈的当前指针。在不改变document的前提下,一旦当前指针改变则会触发onpopstate事件。
popstate事件对象(event)的state属性包含了这个历史记录条目的state对象的一个拷贝.
window.onpopstate = function(event) {
alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
//绑定事件处理函数.
history.pushState({page: 1}, "title 1", "?page=1"); //添加并激活一个历史记录条目 http://example.com/example.html?page=1,条目索引为1
history.pushState({page: 2}, "title 2", "?page=2"); //添加并激活一个历史记录条目 http://example.com/example.html?page=2,条目索引为2
history.replaceState({page: 3}, "title 3", "?page=3"); //修改当前激活的历史记录条目 http://ex..?page=2 变为 http://ex..?page=3,条目索引为3
history.back(); // 弹出 "location: http://example.com/example.html?page=1, state: {"page":1}"
history.back(); // 弹出 "location: http://example.com/example.html, state: null
history.go(2); // 弹出 "location: http://example.com/example.html?page=3, state: {"page":3}
查看张鑫旭大神写的例子。
具体场景实用解析http://www.cnblogs.com/accordion/p/5699372.html#top
浏览器兼容性
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera Safari |
---|---|---|---|---|
replaceState, pushState | 5 | 4.0 (2.0) | 10 | 11.50 |
history.state | 18 | 4.0 (2.0) | 10 | 11.50 |
并不是页面中所有的链接都需要使用PJAX加载,所有在需要这个东西的a标签上加一个属性,如data-pjax=true,然后统一添加事件。