博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
不刷新改变URL: pushState + Ajax
阅读量:7216 次
发布时间:2019-06-29

本文共 2761 字,大约阅读时间需要 9 分钟。

如果你玩过+,看到过YouTube的新界面,便会体验到这个HTML5的新功能。使用pushState + Ajax(pjax),可以实现网页的ajax加载,同时又能完成URL的改变而没有网页跳转刷新的迹象,就像是改变了网页的hash(#)一样。

指引 / 跳至

旧的解决方案

曾说SEO和ajax是天敌。此前从开始流行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是不能改变网页标题的哦。

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调用风格。以为例,为了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

 + PJAX 插件

已经,有人把PJAX做成了,方便调用,节省大量代码:

if ($.support.pjax) {

$(document).on('click', 'a[data-pjax]', function(event) {

var container = $(this).closest('[data-pjax-container]')

$.pjax.click(event, {container: container})

});}

转载于:https://www.cnblogs.com/chris-oil/p/5020918.html

你可能感兴趣的文章
2.Web中使用iReport 整合----------创建html格式的
查看>>
异常备忘:java.lang.UnsupportedClassVersionError: Bad version number in .class file
查看>>
最全三大框架整合(使用映射)——applicationContext.xml里面的配置
查看>>
初步理解Java的三大特性——封装、继承和多态
查看>>
知识点积累(一)
查看>>
iphone-common-codes-ccteam源代码 CCFile.m
查看>>
python:浅析python 中__name__ = '__main__' 的作用
查看>>
修改tomcat端口后不能IP访问问题
查看>>
review board
查看>>
URAL 1495 One-two, One-two 2
查看>>
牛客国庆集训派对Day3 G Stones
查看>>
虚函数简单总结
查看>>
插入排序--算法导论
查看>>
NoSQL -- Redis使用
查看>>
处理iphone的 .play() 不能播放问题
查看>>
jetty404web界面服务器信息隐藏
查看>>
22个Photoshop网页设计教程网站推荐
查看>>
如何让程序员更容易的开发Web界面?重构SmartAdmin展示TinyUI
查看>>
centos7 python2和python3共存
查看>>
rhel6.2配置在线yum源
查看>>