不刷新改变URL: pushState + Ajax

标签: 改变 url pushstate | 发表时间:2015-06-13 02:56 | 作者:天梯梦
出处:http://www.iteye.com

如果你玩过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。不过如果你觉得这个#!很好看就没关系了。

twtter-hash

 

新的解决方案: 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是不能改变网页标题的哦。

 

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请求输出专门的内容。

流程图示意

这个例子的大致过程如下图所示

ajax-pushstate-example

 

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})

});}

 

 

 

谢谢收看,如有不正请指出。

 

下载: jquery-pjax-master

原文: http://blog.netsh.org/posts/pushstate-ajax_1339.netsh.html

 

justcode.ikeepstudying.com

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [改变 url pushstate] 推荐:

不刷新改变URL: pushState + Ajax

- - Web前端 - ITeye博客
如果你玩过Google+,看到过YouTube的新界面,便会体验到这个HTML5的新功能. 使用pushState + Ajax(pjax),可以实现网页的ajax加载,同时又能完成URL的改变而没有网页跳转刷新的迹象,就像是改变了网页的hash(#)一样. 曾说SEO和ajax是天敌. 此前从Twitter开始流行Ajax+hash的方式调用内容,Google给出的解决方案是“#.

ajax与HTML5 history pushState/replaceState实例

- - 张鑫旭-鑫空间-鑫生活
本文地址: http://www.zhangxinxu.com/wordpress/?p=3432. 我就TM想找个例子,知道如何个使用,使用语法什么的滚粗. 精力总是有限的,昨天一冲动,在上海浦东外环之外订了个90米的房子,要借钱筹首付、贷款和领证什么的. HTML5 history相关知识点啪啦啪啦讲起来也是一条又臭又长的裹脚布,精气神实在不够用,这里,直接一个实例.

URL的井号

- chenqj - 阮一峰的网络日志
一个显著变化,就是URL加入了"#!"符号. 在我印象中,这是主流网站第一次将"#"大规模用于直接与用户交互的关键URL中. 这表明井号(Hash)的作用正在被重新认识. 本文根据HttpWatch的文章,整理与井号有关的所有重要知识点. 其右面的字符,就是该位置的标识符. 就代表网页index.html的print位置.

将URL编码?

- - JavaScript - Web前端 - ITeye博客
    URL一般只能由字母、数字、$ - _. * ' ( ) 等一些字符构成. 那么当URL中需要用到汉字时怎么办,譬如有这样的URL: "www.test.com/search?name=张三",此时,只有通过将URL进行编码的方式进行传递了.     Javascript编/解码方法:.     如果对上面的URL(www.test.com/search?name=张三)进行编码的话.

理清URL编码

- winners - Thinking for Fun
关于URL编码,RFC1738做了如下的规定:. “Only alphanumerics [0-9a-zA-Z], the special characters “$-_.+!*’(),” [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL.”.

iOS UIWebView URL拦截

- - 移动开发 - ITeye博客
本文译者: candeladiao,原文: URL filtering for UIWebView on the iPhone. 说明:译者在做app开发时,因为页面的javascript文件比较大导致加载速度很慢,所以想把javascript文件打包在app里,当UIWebView需要加载该脚本时就从app本地读取,但UIWebView并不支持加载本地资源.

URL最大长度问题

- - CSDN博客推荐文章
这几天为解决一个BUG头疼了一段时间,BUG现象如下:. 一个选择人员的选择控件,当选择多个人时(50多个的时候),返回没有错误现象,而再一次打开的时候就报404错误. 看到这个错误非常纳闷,无法下手,只能再一次看控件的代码,在详细看代码时,发现所有的参数都是经过URL传参的,赶紧百度一下URL参数的大小限制(从这个百度开始,我就进入一个误区:参数大小的限制).

URL中井号的作用

- - CSDN博客Web前端推荐文章
  URL中的井号(#)是比较常见的,它并不影响网址的指向,而是有众多功能和特点的. 下面就为大家介绍一些有关井号的故事.   1、页面中的某一个位置可以用井号在URL中指定.   井号作为比较长出现在URL的一种符号,通常也会代表这个页面中的某一个位置,比如:http://aoshu.juren.com/chzt/xiaoxueshijuan/index.html#nn1,此URL表示在这个页面中nn1的位置.

APP调用Custom URL Scheme

- - IT技术博客大学习
标签:   Scheme   跳转. Custom URL scheme 的好处就是,你可以在其它程序中通过这个url打开应用程序. 如A应用程序注册了一个url scheme:myApp,  那么就在mobile浏览器中就可以通过打开你的应用程序A. 首先在AndroidManifast.xml要被指定Scheme的Activity下设置如下参数.