如何控制浏览器的历史记录

In: 前端开发

5 09 2008

上次一位网友在我blog留言问到如何修正Ajax后退失效,这是在开发Ajax应用时很常见的需求。这篇文章就简单的介绍一下怎么解决这个问题。

首先我们要清楚后退按钮会失效的原因:使用Ajax时,页面通过XMLHttpRequest来更新内容,并没有Redirect,所以浏览器不会出现前进后退。这也是Ajax刚出来时遭到很多人批判的一个原因,其中细节可以参考这两篇文章《Ajax: 99% Bad》、《AJAX的七宗罪》。这个问题其实跟Ajax无关,不过Ajax的出现使得一个页面实现无刷新更新更容易,这个时候人们开始意识到,一个页面发生巨大改变而不能后退是一件很痛苦的事情。

要解决这个问题,就要控制浏览器的history,在页面发生改变时往浏览器历史里插入一条记录。但是出于安全的目的,JS是不能直接操作history的。我们必须采用其他方法:IE中,在页面中插入一个隐藏的iframe,通过改变iframe的location或者DOM,都可以在主窗口的history中产生新记录,详细研究可以参考这篇文章;在其他浏览器(Firefox、Opera、Safari)中没有这么复杂,只需改变url就可以产生一条新的history记录,当然url不能乱改,要不页面就跳转走了,通常我们改变的是location.hash,也就是url“#”以后的部分。下面是具体实现:

首先在页面中放一个隐藏的iframe:

<style type="text/css" title="default" media="screen">
#history_iframe{position:absolute;top:0; left:0;width:1px; height:1px;visibility:hidden}
</style>
<iframe id="history_iframe" src="blank.html"></iframe>

blank.html的内容也很简单,放了一个div来存当前的hash:

<html>
 
<head><title>hack iframe</title></head>
 
<body><div id="state"></div></body>
</html>

对不同浏览器采用不同方法控制history:

var isIE = typeof(window.opera)!="object"&&window.navigator.userAgent.indexOf("MSIE")>0;
var $ = function(s){return document.getElementById(s)};
function update_status(str){
 
if(isIE){
    
try{
      
var doc = $("history_iframe").contentWindow.document;
      
doc.open();
      
doc.write('<html><body><div id="state">'+str+'</div></body></html>');
      
doc.close();
    
}catch(e){}
 
}
 
location.hash = str;
};

可以测试一下了:

<button onclick="update_status('test1')" >test1</button>
<button onclick="update_status('test2')" >test2</button>
<button onclick="update_status('test3')" >test3</button>

上面就是控制浏览器history的基本原理,通过点击三个按钮,会往浏览器写入三条历史记录,这样尽管页面依旧没有刷新,但是浏览器的前进后退却能开始工作了。剩下的工作很简单:利用一个定时器不停的检测状态是否发生变化(IE检测iframe里state的innerText;其他浏览器检测location.hash),然后在检测到状态改变时调用相应的方法还原页面内容。限于篇幅,这一部分代码就不贴出来了。完整的实例在这里

再来看看这些吧

Comment Form

关于我

JerryQu,当前从事前端开发,@中国北京
这里是我随便记录东西的地方~
需要找我,我的联系方式在这里 »
查找QGYWebim相关信息,请点这里 »

  • 来无影: 这个站的模板不错,我很喜欢![:13 [...]
  • 莞尔: 我用了你的表情插件发现一个问题 那就是路径问题 我的WP没有放在根目录 [...]
  • samuel: 很棒。你自己写的demo,比去看jquery代码简单多了 [...]
  • samuel: 非常棒,很有参考价值。比去看jQuery代码舒服多了 [...]
  • 风剪云: 向你学习了。BS无德之人,拿去用也罢了。居然还拿去赚钱。[:11 [...]
  • nvshao: [:20]不错不 [...]
  • 团伙创意: bu cuo 不错 学习啦~ [...]
  • 3g培训: 再来看看。上班没事干。还是希望看到新文 [...]

共享