• 沙里软件

  • ShaliSoft.com [手机站]   办公桌收纳抽屉
  • 首页
  • 博文
  • 演示
  • 管理
  • 利用history.pushState让Ajax改变URL

    网络   2014/5/14 23:29:29

    如果你玩过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是不能改变网页标题的哦。

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

    流程图示意

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

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

    });}

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


    阅读(923) 分享(0)

    上一篇: window.location.hash属性介绍
    下一篇: 正确的jQuery加载方式

  • 精彩推荐

    ◆ 安装完office后 在组件服务里DCOM配置中找不到
    ◆ 微信清缓存工具,微信怎么清理缓存?
    ◆ 用回溯法解决子集和问题【C#版本】
    ◆ 实测什么物体会影响WIFI信号
    ◆ 利用UC微信分享接口进行WEB微信分享
    ◆ ASP.NET之GridView Eval() 中数据格式化或格式化数据
    ◆ css常用hack语法
    ◆ 面向对象的缺点,你了解了吗
    ◆ 我国首台可人脸识别ATM机发布 不刷脸不能取钱
    ◆ 2G网络要关闭了吗?你还不打算换4G手机?
  • 用心做事 不能唯利是图

    • 吊儿
    • 用QQ联系我17905772
  • 搜索


  • 最新文章

    • 导出Excel 格式 mso-number-format
    • 服务器iis支持tls1.2,windows server 2008 r2 中IIS启用TLS 1.2(安装SSL后用TLS 1.2)
    • MySQL配置优化
    • EditPlus 添加文件比较工具winmerge
    • 滚动悬浮固定JS特效

  • 热门文章

    • php sso单点登录实现代码
    • 中国菜刀(China chopper) 最新黑客工具
    • redis.conf中文版(基于2.4)
    • 搜索引擎名单大全
    • php图片上传类,支持加水印,生成略缩图

  • 最新图库


  • 最新评论


  • 友情链接

  • 沙里软件

  • 最近访客

    Powered by ShaliSoft.com 豫ICP备13008529号

    免责声明:本站部分内容来源于互联网,转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,不为其版权负责,也不构成任何其他建议。如果发现侵犯版权,联系QQ17905772进行删除。