关于Ajax后退按钮的实现

众所周知,Ajax给网页带来了翻天覆地的革新,让javascript从程序员或是美工随便写写的脚本语言成为一门非常重要的网页脚本语言,渐渐被人接受,地位也逐步提高,虽然javascript还存在很多糟粕,这里推荐一本书《JavaScript语言精粹(JavaScript.The.Good.Parts)》(说句题外话,这本书是淘宝前端LEADER小马翻译的,当时是我参加D2论坛GOOGLE的前端工程师HEDGE送我的,哈哈!),封面是一只蝴蝶,这本书我看了3遍,还准备再多研究几遍,虽然很薄,但是内容的广泛和深度是非常大的。这本书的作者则是:Douglas Crockford,他是JavaScript开发社区最知名的权威,是JSON、JSLint、JSMin和ADSafe之父,目前是Yahoo的资深JavaScript架构师,JavaScript的发明人Brendan Eich说他是“Yoda of lambda programming and JavaScript(lambda编程和JavaScript的精神领袖)”。

回归主题,Ajax带来的技术革新,同时使后退按钮失效,额外增加代码维护成本,以及无法SEO,都是Ajax的缺点,虽然这些缺点无法掩盖它诸多革命性的优点。本文就Ajax开发时,利用欺骗浏览器的办法实现浏览器后退按钮的功能,本文只阐述实现原理配合部分代码,没有提供相关实例,具体实例可以去百度一下。

方法一: iframe法
目前主流实现Ajax后退按钮都是利用iframe方法,Yahoo!和google好像都是这样做的。其原理是往页面内插入一个隐藏的


利用修改这个iframe的src属性的值来欺骗浏览器,简单的实现就是将每次Ajax传输过来的JSON数据存入一个数组,然后将这个数组传递到iframe中,恢复函数写在iframe页面中,每次点后退其实就是后退iframe页面里的内容,然后执行iframe里的恢复函数达到后退效果,数据恢复函数的编写则根据实际情况千变万化。
例如:
后台传递过来不同的name值,比如发了3次请求后,接收数据数组就变成:
back_array // [{name:”wzh”},{name:”snoopy”},{name:”163”}];
然后每次Ajax请求回调函数里则可以修改iframe的src值为:name_api.php?l=2;
所以在iframe里的恢复数据函数直接就可以取到src内l的值为2,也就是当前接收到的数据是:
back_arry[2].name //163
同理,如果用户点了后退,iframe的src值为:name_api.php?l=1;则用户当前接收的数据是:
back_arry[1].name //snoopy
这时如果用户点前进,则没有问题,如果用户点击重新发送Ajax并且接受新数据,则我们需要把数组中l+1的数据替换成新的:
back_arry[l+1] = {name:”126”};
基本实现原理就是这样,不过好像safari的实现稍有不同,需要建立一个form表单来进行提交,但是实现过程是一样的。

方法二:hash法
在FF和Chrome下,域名如果改变最后的hash值#xxx,也会被记录到浏览器的历史记录里,目前好像不支持IE8,正是由于这个原因,一个很好的Ajax后退方法被iframe法取代了。hash法能够不用去创建iframe元素,让代码更整洁,更容易开发和维护。具体实现的原理就是:
1、发送Ajax请求,同时将接受到的数据或操作放入一个或多个记录数组里。
2、每次Ajax请求回调时,修改浏览器url的hash值,即location.hash = “#1”或location.hash = “#3”;
3、捕获浏览器hash的change事件,触发恢复函数,进行后退和前进操作。
好了,说到这里感觉其实hash法很简单的,但是关键的关键则是我上面那段话的红色部分!
如何捕获url中hash的change事件!
这里我推荐一个jquery插件叫hashchange.js,他可以给window对象绑定一个changehash事件,然后执行回调函数。
具体例子为: $(window).hashchange( CallBack_fn )
这样就可以捕获hash改变了,但是我们都知道,javascript是无法捕获客户端页面之外的鼠标click事件的,当然也无法直接捕获后退按钮的触发,这里我们打开hashchange.js的开发版本,找到这样两句话:
setInterval(checkHashIE, 100);
setInterval(checkHash, 100);
根据条件的不同来进行ie和非ie的判断,看到这里恍然大悟了,原来hashchange.js是通过不断的轮询来实现捕获url内hash值的改变的,也就是说每100毫秒执行一次checkhash函数。
这样我们就可以利用hash值的改变来实现Ajax后退和前进的按钮了,不过这个办法ie8不兼容,所以使用率不高,不过确实是一个很好的方法。