不刷新改变URL: pushState + Ajax
如果你玩过Google+,看到过YouTube的新界面,便会体验到这个HTML5的新功能。使用pushState + Ajax(pjax),可以实现网页的ajax加载,同时又能完成URL的改变而没有网页跳转刷新的迹象,就像是改变了网页的hash(#)一样。
指引 / 跳至
旧的解决方案
曾说SEO和ajax是天敌。此前从Twitter开始流行Ajax+hash的方式调用内容,Google给出的解决方案是“#!~string”自动转换为“?_excaped_fragment_=~string”来抓取动态内容。但这无疑会非常麻烦:首先你需要对网站进行“?_excaped_fragment_=~string”的处理配置,而且,如果用户把网址“http://example.com/#!/~string”直接复制并分享的话,意味着网页还必须监听hashchange。不过如果你觉得这个#!很好看就没关系了。

新的解决方案: pushState
然而HTML5的新接口pushState / replaceState就可以比较完美的解决问题,它避免了改变hash的问题,避免了用户不理解URL的形式感到疑惑,同时还有onpopstate提供监听,良好响应后退前进。而且它不需要这个URL真实存在。
HTML5 的 pushState+Ajax
HTML5提供history接口,把URL以state的形式添加或者替换到浏览器中,其实现函数正是 pushState 和 replaceState。
pushState 例子
pushState() 的基本参数是:
window.history.pushState(state, title, url);
其中state和title都可以为空,但是推荐不为空,应当创建state来配合popstate监听。
例如,我们通过pushState现改变URL而不刷新页面。
var state = ( {
url: ~href, title: ~title, ~additionalKEY: ~additionalVALUE
} );
window.history.pushState(state, ~title, ~href);
其中带有“~”符号的是自定义内容。就可以把这个~href(URL)推送到浏览器的历史里。如果想要改变网页的标题,应该:
document.title= ~newTitle;
注意只是pushState是不能改变网页标题的哦。
Demo 演示
点我试试 (实现函数onclick = history.pushState( null, null, '/test-string'); )。实际上这个博客在文章之间也部署了这个技术。
replaceState 同理
window.history.replaceState( state, ~title, ~href);
pushState、replaceState 的区别
pushState()可以创建历史,可以配合popstate事件,而replaceState()则是替换掉当前的URL,不会产生历史。
限制因素
只能用同域的URL替换,例如你不能用http://baidu.com去替换http://google.com。而且state对象不存储不可序列化的对象如DOM。
Ajax 配合 pushState 例子
现在用Ajax + pushState来提供全新的ajax调用风格。以jQuery为例,为了SEO需要,应该为a标签的onclick添加方法。
$("~target a").click(function(evt){
evt.preventDefault(); // 阻止默认的跳转操作
var uri=$(this).attr('href');
var newTitle=ajax_Load(uri); // 你自定义的Ajax加载函数,例如它会返回newTitle
document.title=newTitle; // 分配新的页面标题
if(history.pushState){
var state=({
url: uri, title: newTitle
});
window.history.pushState(state, newTitle, uri);
}else{ window.location.href="#!"+~fakeURI; } // 如果不支持,使用旧的解决方案
return false;
});
function ajax_Load(uri){ ... return newTitle; } // 你自定义的ajax函数,例如它会返回newTitle
即可完成pushState。至于新标题newTitle的获取就是另外的问题了,例如你可以为a标签分配data-newtitle=~title属性并届时读取,或者如果你用的$.ajax()函数,可以用$(result).filter("title").text()来获取。
另外如果需要对新加载的页面的连接同样使用这个ajax,则需要对新内容的a标签重新部署,例如
$("~newContentTarget a").click(function(evt){ ... });
pushState 配合 popstate 监听
想要良好的支持浏览器的历史前进后退操作,应当部署popstate监听:
window.addEventListener('popstate', function(evt){
var state = evt.state;
var newTitle = ajax_Load(state.url); //你自定义的ajax加载函数,例如它会返回newTitle
document.title=newTitle;
}, false);
提醒,你可以通过setRequestHeader()来让服务器端配合你的ajax请求输出专门的内容。
流程图示意
这个例子的大致过程如下图所示

jQuery + PJAX 插件
已经在github上发布,有人把PJAX做成了jQuery插件,方便调用,节省大量代码:
if ($.support.pjax) {
$(document).on('click', 'a[data-pjax]', function(event) {
var container = $(this).closest('[data-pjax-container]')
$.pjax.click(event, {container: container})
});}
不刷新改变URL: pushState + Ajax的更多相关文章
- 通过history.pushState无刷新改变url
通过history.pushState无刷新改变url 背景 在浏览器中改变地址栏url,将会触发页面资源的重新加载,这使得我们可以在不同的页面间进行跳转,得以浏览不同的内容.但随着单页应用的增多,越 ...
- history.pushState无刷新改变url
通过history.pushState无刷新改变url 背景 在浏览器中改变地址栏url,将会触发页面资源的重新加载,这使得我们可以在不同的页面间进行跳转,得以浏览不同的内容.但随着单页应用的增多,越 ...
- 使用ajax和history.pushState无刷新改变页面URL
表现 如果你使用chrome或者firefox等浏览器访问本博客.github.com.plus.google.com等网站时,细心的你会发现页面之间的点击是通过ajax异步请求的,同时页面的URL发 ...
- 使用ajax和history.pushState无刷新改变页面URL(转)
表现 如果你使用chrome或者firefox等浏览器访问本博客.github.com.plus.google.com等网站时,细心的你会发现页面之间的点击是通过ajax异步请求的,同时页面的URL发 ...
- HTML5无刷新修改URL
HTML5新添加了两个api分别是pushState和replaceState,DOM中的window对象通过window.history方法提供了对浏览器历史记录的读取,可以在用户的访问记录中前进和 ...
- 使用ajax和window.history.pushState无刷新改变页面内容和地址栏URL
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 使用ajax和history.pushState无刷新改变页面URL onpopstate(转)
Javascript代码 var htmlData1 = $.ajax( { url: "/getXXXResponse", async: false }).re ...
- 使用ajax和window.history.pushState无刷新改变页面内容和地址栏URL (转)
在访问现在很火的google plus时,细心的用户也许会发现页面之间的点击是通过ajax异步请求的,同时页面的URL发生了了改变.并且能够很好的支持浏览器的前进和后退.不禁让人想问,是什么有这么强大 ...
- HTML5之pushstate、popstate操作history,无刷新改变当前url
一.认识window.history window.history表示window对象的历史记录,是由用户主动产生,并且接受javascript脚本控制的全局对象.window对象通过history对 ...
随机推荐
- PHP面向对象——静态属性和静态方法
静态属性 所谓静态属性,也就是这个属性对于这个类来说是唯一的,不管有多少个对象,只要它引用了一个静态对象,那么这些对象引用出来的值肯定是同一个. 静态变量不能使用->这种箭头符号,而是使用::这 ...
- php 审核管理
权限管理界面 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...
- 数据结构和算法 – 6.构建字典: DictionaryBase 类和 SortedList 类
6.1.DictionaryBase 类的基础方法和属性 大家可以把字典数据结构看成是一种计算机化的词典.要查找的词就是关键字,而词的定义就是值. DictionaryBase 类是一种用作专有字 ...
- Spring Boot的快速启动和部署
>>关于Spring Boot 这是官网描述的特点: 1.Create stand-alone Spring applications 创建独立的Spring应用 2.Embed Tomc ...
- Ubuntu中给eclipse和android studio添加桌面快捷图标
Ubuntu 12.04 创建应用程序启动项(可在Unity LaucherPad显示) http://www.cnblogs.com/bluestorm/archive/2012/10/12/272 ...
- Delphi运算符总结
分类 运算符 操作 操作数 结果类型 范例 算术运算符(加法.减法和乘法运算符的结果为参加运算的两个数据中的精度高的类型) + 加 整数,实数 整数,实数 X + Y - 减 整数,实数 整数,实数 ...
- Shell编程基础教程3--Shell输入与输出
3.Shell输入与输出 3.1.echo echo命令可以显示文本行或变量,或者把字符串输出到文件 echo [option] string ...
- Linux光纖卡配置,磁盤掛載,多路徑設置
Linux光纖卡配置 1.首先根據光纖卡類型加載對應的驅動.我這裡常用的是QLogic和Brocade光纖卡 [root@rhcsasm2 host3]# lspci | grep Fibre - ...
- Session 类
Session 类 Session 类可以使用户在浏览您的网站时,维持他们的状态并跟踪他们的行为. Session 类将每个用户的 session 信息序列化(serialize)后存储到到 coo ...
- JavaScript前端框架的思考
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:现在JavaScript前端框架层出不穷,尤其Angular进入到2.x时候之后,我们 ...