单页面时代 - Ajax应用可以改变用户的 URL 地址栏并且支持后退按钮

详细内容参看 :http://codecampo.com/topics/84

CodeCampo 是一个小型开发者社区,其代码开源托管于Github,作者@chloerei订阅@codecampo

本人做了归纳与调整。


一、有两个问题需要克服 1. Javascript 有一个函数可以改变当前 URL 路径,并载入页面。 window.location = '/' 而如果只改变 URL 的 # 号后面部分,不会导致浏览器重新载入网页。 window.location = '#here' //不会导致页面刷新 2. 浏览器不懂得记录 Ajax 调用的状态。 3. 从非 Ajax 页面返回到 Ajax 页面。处理所有的细节的话,这问题比较棘手存。 采访的方法,让其不存在此情况 : 采用若打开非ajax页面,target="_blank" 二、目标 理想中应该让 Ajax 调用达到这样的状态: 如果 Ajax 调用后的页面逻辑上已经跟之前不是同一个页面,那么 URL 应该随之改变。 前提同上,那么在新页面点击浏览器的后退按钮,应该回到 Ajax 调用前的页面。 三、方案 1. 只改变 URL Hash 的单页面应用 , 对主流浏览器的支持程度很高。 现在的 Twitter,Google,Facebook 的 URL 地址充斥着 #号或者 #! 号。例如一个新版 Twitter 地址是这样的 https://twitter.com/#!/chloerei 其原理:#号后面的改变不会导致页面加载 步骤: step1: 有关 Ajax 调用链接全部用 #path 作为链接目标 step2: 设置 onhashchange 事件 (窗口 window 对象的 hash 值(# 号后面部分)发生变化时,会调用 onhashchange 事件。) 在此事件里面,调用ajax方法。如: window.onhashchange = function(){ ajax方法 } 此方案的副作用 : 把路径写在了 Hash 里面破坏了 URL 原先的含义。 2. 基于 history.pushState API 只支持对HTML5 友好的浏览器 步骤: step1: 在发送 ajax 请求之前把目标地址推进浏览器的历史记录. (HTML5 新增了 history.pushState 方法,用以向浏览器添加历史记录,但是不触发页面载入) if (history && history.pushState) { history.pushState(null,document.title,this.href); } step2: 处理后退按钮. 浏览器后退的时候会触发 onpopstate 事件,所以要给这个事件挂上处理方法。 if (history && history.pushState) { $(window).bind("popstate",function() { $.getScript(location.href); }); } step3: 从非 Ajax 页面返回到 Ajax 页面 (也可以不需要step3,采用若打开非ajax页面,target="_blank") 这时候要做两个处理: 1)要求 Ajax 相关页面不缓存 (缺点:牵扯到性能) 2)处理 popstate 的方法增加一个标志位,第一次载入页面的时候不要调用后面的逻辑。 if (history && history.pushState) { var loaded = false; $(window).bind("popstate",function() { if (!loaded) { loaded = true; } else { $.getScript(location.href); } }); } 3. 综合以上两种方案 : 若浏览器有支持history.pushState,则采用方案2 ,否则采用方案1 。 代码实现如下 step1: 在发送 ajax 请求之前 . 设置两种不同写法的url if (history && history.pushState){ history.pushState(null,this.href); }else{ // 不支持 history.pushState // #path 作为链接目标 window.location = "#!path"; } step2: 处理回退按钮 if (history && history.pushState){ var loaded = false; $(window).bind("popstate",function() { if (!loaded) { loaded = true; } else { $.getScript(location.href); } }); }else { // 不支持 history.pushState window.onhashchange = function(){ ajax方法 } }

相关文章

IE6是一个非常老旧的网页浏览器,虽然现在很少人再使用它,但...
PHP中的count()函数是用来计算数组或容器中元素的个数。这个...
使用 AJAX(Asynchronous JavaScript and XML)技术可以在不...
Ajax(Asynchronous JavaScript and XML)是一种用于改进网页...
本文将介绍如何通过AJAX下载Excel文件流。通过AJAX,我们可以...
Ajax是一种用于客户端和服务器之间的异步通信技术。通过Ajax...