`
天梯梦
  • 浏览: 13624579 次
  • 性别: Icon_minigender_2
  • 来自: 洛杉矶
社区版块
存档分类
最新评论

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

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

 

分享到:
评论

相关推荐

    使用Yii整合的pjax(pushstate+ajax)实现无刷新加载页面

    BOM对象history被增强了一波,主要是对历史栈的操作,以前只有 replace , go 之类的,都会跳转并刷新整个页面,现在有了 pushState , replaceState 等等单纯操作历史栈的方法,只是单纯修改历史栈里的内容,没有副...

    pushState实现Ajax无刷新页面切换

    pushState()有三个参数:一个状态对象、一个标题(现在会被忽略),一个可选的URL地址。 state:与要跳转到的URL对应的状态信息。 title:空字符串(以后可能有用)。 url:要跳转到的URL地址,不能跨域。 作用:...

    original-pushstate-ajax

    原pushstate的ajax 使用pushstate和replacestate,popstate存储url状态 使用ajax交换数据 pushstate + ajax技术适用于某些我们不希望刷新页面的页面,但坏处对seo不利

    使用ajax和history.pushState无刷新改变页面URL示例

    HTML5里引用了新的API,history.pushState和history.replaceState,就是通过这个接口做到无刷新改变页面URL的。 与传统的AJAX的区别 传统的ajax有如下的问题: 1、可以无刷新改变页面内容,但无法改变页面URL 2、...

    使用ajax实现无刷新改变页面内容和地址栏URL

    HTML5里引用了新的API,就是history.pushState和history.replaceState,就是通过这个接口做到无刷新改变页面URL的。 与传统的AJAX的区别 传统的ajax有如下的问题: 虽然ajax可以无刷新改变页面内容,但无法改变页面...

    浅谈通过JS拦截 pushState和replaceState事件

    history.pushState 和 history.replaceState 可以在不刷新当前页面的情况下更改URL,但是这样就无法获取通过AJAX得到的新页面的内容了。 虽然各种HTML5文档说 [removed] 事件可以拦截 pushState 的消息,但在实际的...

    使用pjax实现无刷新更改页面url

    pjax=pushState+ajax,相信用过github的同学都知道,github部分页面采用了pjax这个项目来实现ajax无刷新加载的同时改变页面url。一起来学习一下这个插件吧。

    pushState、replaceState、onpopstate 实现Ajax页面的前进后退刷新

    使用Ajax可以异步获取数据,可以更高效地渲染页面。 但也存在这一些问题: 再刷新页面,页面就会变成初始的状态 浏览器的前进后退功能无效 对搜索引擎的爬虫抓取不友好 1、 早前会使用浏览器的 hash锚点 来解决 不同...

    通过history解决ajax不支持前进/后退/刷新的问题

    现在前后端基本都是通过ajax实现前后端接口数据的交互,但是,ajax有个小小的劣势,即:不支持浏览器“后退”和“前进“键。 但是,现在我们可以通过H5的histroy属性 解决ajax在交互请求的这个小bug。 事件描述: H5...

    解决微信内置浏览器返回上一页强制刷新问题方法

    1.0、通过history API的 history.pushState或 history.replaceState 保存AJAX状态; 2.0、同时将AJAX获取到的数据缓存起来(可以考虑使用H5的localStorage或sessionstorage); 3.0、当返回到这个页面时,先获取窗口...

    前端学科面试宝典面试题下载完整题目答案

    HTML5 History两个新增的API:history.pushState 和 history.replaceState,两个 API 都会操作浏览器的历史记录,而不会引起页面的刷新。 Hash就是url 中看到 # ,我们需要一个根据监听哈希变化触发的事件( ...

    Html5无刷新修改browser Url的方法

    window.history.pushState(object, title, new_url) — 在window.history里新增一个历史记录点 window.history.replaceState(object, title, new_url) — 在window.history替换当前page的历史记录点 object – ...

    barba.js:JavaScript实现的平滑页面过渡特效-javascript

    使用 Push State API 更改 URL。 开始通过 XMLHttpRequest 获取新页面。 创建一个新的过渡实例。 加载新页面后,barba.js 会解析新的 HTML(采用 .barba-container)并将新内容放在 #barba-wrapper 内的 DOM 上...

Global site tag (gtag.js) - Google Analytics