<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JerryQu的小站 &#187; Browser History</title>
	<atom:link href="http://www.qgy18.com/tag/browser-history/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.qgy18.com</link>
	<description></description>
	<lastBuildDate>Tue, 16 Mar 2010 03:42:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>如何控制浏览器的历史记录</title>
		<link>http://www.qgy18.com/2008/09/howto_control_browser_history/</link>
		<comments>http://www.qgy18.com/2008/09/howto_control_browser_history/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 07:07:23 +0000</pubDate>
		<dc:creator>Jerry Qu</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Browser History]]></category>

		<guid isPermaLink="false">http://www.qgy18.com/?p=46</guid>
		<description><![CDATA[上次一位网友在我blog留言问到如何修正Ajax后退失效，这是在开发Ajax应用时很常见的需求。这篇文章就简单的介绍一下怎么解决这个问题。 首先我们要清楚后退按钮会失效的原因：使用Ajax时，页面通过XMLHttpRequest来更新内容，并没有Redirect，所以浏览器不会出现前进后退。这也是Ajax刚出来时遭到很多人批判的一个原因，其中细节可以参考这两篇文章《Ajax: 99% Bad》、《AJAX的七... ]]></description>
			<content:encoded><![CDATA[<p>上次一位网友在我blog留言<a href="http://www.qgy18.com/2008/09/browser_history_back/#comment-29">问到如何修正Ajax后退失效</a>，这是在开发Ajax应用时很常见的需求。这篇文章就简单的介绍一下怎么解决这个问题。</p>
<p>首先我们要清楚后退按钮会失效的原因：使用Ajax时，页面通过XMLHttpRequest来更新内容，并没有Redirect，所以浏览器不会出现前进后退。这也是Ajax刚出来时遭到很多人批判的一个原因，其中细节可以参考这两篇文章《<a href="http://www.johnniemanzari.com/archives/2005/05/ajax_99_bad.html">Ajax: 99% Bad</a>》、《<a href="http://tech.163.com/05/1009/18/1VL1PAP300091589.html">AJAX的七宗罪</a>》。这个问题其实跟Ajax无关，不过Ajax的出现使得一个页面实现无刷新更新更容易，这个时候人们开始意识到，一个页面发生巨大改变而不能后退是一件很痛苦的事情。</p>
<p>要解决这个问题，就要控制浏览器的history，在页面发生改变时往浏览器历史里插入一条记录。但是出于安全的目的，JS是不能直接操作history的。我们必须采用其他方法：IE中，在页面中插入一个隐藏的iframe，通过改变iframe的location或者DOM，都可以在主窗口的history中产生新记录，详细研究可以参考<a href="http://codinginparadise.org/weblog/2005/08/ajax-tutorial-tale-of-two-iframes-or.html">这篇文章</a>；在其他浏览器(Firefox、Opera、Safari)中没有这么复杂，只需改变url就可以产生一条新的history记录，当然url不能乱改，要不页面就跳转走了，通常我们改变的是location.hash，也就是url“#”以后的部分。下面是具体实现：<br />
<span id="more-46"></span><br />
首先在页面中放一个隐藏的iframe：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Olive;">&lt;</span><span style="color: Green;">style</span><span style="color: Gray;"> </span><span style="color: #00008b;">type</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">text/css</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: #00008b;">title</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">default</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: #00008b;">media</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">screen</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br />#history_iframe{position:absolute;top:0; left:0;width:1px; height:1px;visibility:hidden} <br /></span><span style="color: Olive;">&lt;/</span><span style="color: Green;">style</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br /></span><span style="color: Olive;">&lt;</span><span style="color: Green;">iframe</span><span style="color: Gray;"> </span><span style="color: #00008b;">id</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">history_iframe</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: #00008b;">src</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">blank.html</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">&gt;&lt;/</span><span style="color: Green;">iframe</span><span style="color: Olive;">&gt;</span></div></div>
<p>blank.html的内容也很简单，放了一个div来存当前的hash：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Olive;">&lt;</span><span style="color: Green;">html</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br />&nbsp; </span><span style="color: Olive;">&lt;</span><span style="color: Green;">head</span><span style="color: Olive;">&gt;&lt;</span><span style="color: Green;">title</span><span style="color: Olive;">&gt;</span><span style="color: Gray;">hack iframe</span><span style="color: Olive;">&lt;/</span><span style="color: Green;">title</span><span style="color: Olive;">&gt;&lt;/</span><span style="color: Green;">head</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br />&nbsp; </span><span style="color: Olive;">&lt;</span><span style="color: Green;">body</span><span style="color: Olive;">&gt;&lt;</span><span style="color: Green;">div</span><span style="color: Gray;"> </span><span style="color: #00008b;">id</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">state</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">&gt;&lt;/</span><span style="color: Green;">div</span><span style="color: Olive;">&gt;&lt;/</span><span style="color: Green;">body</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br /></span><span style="color: Olive;">&lt;/</span><span style="color: Green;">html</span><span style="color: Olive;">&gt;</span></div></div>
<p>对不同浏览器采用不同方法控制history：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">isIE</span><span style="color: Gray;"> = </span><span style="color: Green;">typeof</span><span style="color: Olive;">(</span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">opera</span><span style="color: Olive;">)</span><span style="color: Gray;">!=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">object</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;">&amp;&amp;</span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Teal;">navigator</span><span style="color: Gray;">.</span><span style="color: Blue;">userAgent</span><span style="color: Gray;">.</span><span style="color: Blue;">indexOf</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">MSIE</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">&gt;</span><span style="color: Maroon;">0</span><span style="color: Gray;">;<br /></span><span style="color: Green;">var</span><span style="color: Gray;"> $ = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">s</span><span style="color: Olive;">){</span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Teal;">document</span><span style="color: Gray;">.</span><span style="color: Blue;">getElementById</span><span style="color: Olive;">(</span><span style="color: Blue;">s</span><span style="color: Olive;">)}</span><span style="color: Gray;">;<br /></span><span style="color: Green;">function</span><span style="color: Gray;"> </span><span style="color: Blue;">update_status</span><span style="color: Olive;">(</span><span style="color: Blue;">str</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">isIE</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">try</span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">doc</span><span style="color: Gray;"> = $</span><span style="color: Olive;">(</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">history_iframe</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">contentWindow</span><span style="color: Gray;">.</span><span style="color: Teal;">document</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">doc</span><span style="color: Gray;">.</span><span style="color: Blue;">open</span><span style="color: Olive;">()</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">doc</span><span style="color: Gray;">.</span><span style="color: Blue;">write</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">&lt;html&gt;&lt;body&gt;&lt;div id=&quot;state&quot;&gt;</span><span style="color: #8b0000;">'</span><span style="color: Gray;">+</span><span style="color: Blue;">str</span><span style="color: Gray;">+</span><span style="color: #8b0000;">'</span><span style="color: Red;">&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">doc</span><span style="color: Gray;">.</span><span style="color: Blue;">close</span><span style="color: Olive;">()</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Green;">catch</span><span style="color: Olive;">(</span><span style="color: Blue;">e</span><span style="color: Olive;">){}</span><span style="color: Gray;"><br />&nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp; </span><span style="color: Blue;">location</span><span style="color: Gray;">.</span><span style="color: Blue;">hash</span><span style="color: Gray;"> = </span><span style="color: Blue;">str</span><span style="color: Gray;">;<br /></span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></div></div>
<p>可以测试一下了：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Olive;">&lt;</span><span style="color: Green;">button</span><span style="color: Gray;"> </span><span style="color: #00008b;">onclick</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">update_status('test1')</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: Olive;">&gt;</span><span style="color: Gray;">test1</span><span style="color: Olive;">&lt;/</span><span style="color: Green;">button</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br /></span><span style="color: Olive;">&lt;</span><span style="color: Green;">button</span><span style="color: Gray;"> </span><span style="color: #00008b;">onclick</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">update_status('test2')</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: Olive;">&gt;</span><span style="color: Gray;">test2</span><span style="color: Olive;">&lt;/</span><span style="color: Green;">button</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br /></span><span style="color: Olive;">&lt;</span><span style="color: Green;">button</span><span style="color: Gray;"> </span><span style="color: #00008b;">onclick</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">update_status('test3')</span><span style="color: #8b0000;">&quot;</span><span style="color: Gray;"> </span><span style="color: Olive;">&gt;</span><span style="color: Gray;">test3</span><span style="color: Olive;">&lt;/</span><span style="color: Green;">button</span><span style="color: Olive;">&gt;</span></div></div>
<p>上面就是控制浏览器history的基本原理，通过点击三个按钮，会往浏览器写入三条历史记录，这样尽管页面依旧没有刷新，但是浏览器的前进后退却能开始工作了。剩下的工作很简单：利用一个定时器不停的检测状态是否发生变化（IE检测iframe里state的innerText；其他浏览器检测location.hash），然后在检测到状态改变时调用相应的方法还原页面内容。限于篇幅，这一部分代码就不贴出来了。<a href="http://www.qgy18.com/lab/history/">完整的实例在这里</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.qgy18.com/2008/09/howto_control_browser_history/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>不同浏览器处理后退的一些异同</title>
		<link>http://www.qgy18.com/2008/09/browser_history_back/</link>
		<comments>http://www.qgy18.com/2008/09/browser_history_back/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 16:55:26 +0000</pubDate>
		<dc:creator>Jerry Qu</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[Browser History]]></category>

		<guid isPermaLink="false">http://www.qgy18.com/?p=44</guid>
		<description><![CDATA[以前在测试自己写的webim时发现firefox有一个很人性化的特性：在页面上跟别人聊天的时候如果不小心点到了本页打开的链接，只要点一下Firefox的后退按钮，就会退后到之前的页面，可以接着聊。也就是说在firefox中点击后退，原来页面的状态会还原，包括JS改变的DOM结构也会保持。 我们用下面的代码来测试一些常见的浏览器是怎么处理后退的。测试的浏览器有IE8beta2、Firefox3.0.1... ]]></description>
			<content:encoded><![CDATA[<p>以前在测试自己写的webim时发现firefox有一个很人性化的特性：在页面上跟别人聊天的时候如果不小心点到了本页打开的链接，只要点一下Firefox的后退按钮，就会退后到之前的页面，可以接着聊。也就是说在firefox中点击后退，原来页面的状态会还原，包括JS改变的DOM结构也会保持。</p>
<p>我们用下面的代码来测试一些常见的浏览器是怎么处理后退的。测试的浏览器有IE8beta2、Firefox3.0.1、Flock1.2.4(Firefox2.0.0.16内核)、Safari3.1(window版)、Opera9.60。</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Olive;">&lt;</span><span style="color: Green;">a</span><span style="color: Gray;"> </span><span style="color: #00008b;">href</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">http://www.baidu.com</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">&gt;</span><span style="color: Gray;">百度</span><span style="color: Olive;">&lt;/</span><span style="color: Green;">a</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br /></span><span style="color: Olive;">&lt;</span><span style="color: Green;">div</span><span style="color: Gray;"> </span><span style="color: #00008b;">id</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">a1</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">&gt;&lt;/</span><span style="color: Green;">div</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br /></span><span style="color: Olive;">&lt;</span><span style="color: Green;">script</span><span style="color: Gray;"> </span><span style="color: #00008b;">type</span><span style="color: Gray;">=</span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">text/javascript</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">&gt;</span><span style="color: Gray;"><br />&nbsp; window.onload = function(){<br />&nbsp;&nbsp; &nbsp;alert(&quot;load&quot;);<br />&nbsp;&nbsp; &nbsp;var i = 1;<br />&nbsp;&nbsp; &nbsp;setInterval(function(){<br />&nbsp;&nbsp; &nbsp; &nbsp;document.getElementById(&quot;a1&quot;).innerHTML = i++;<br />&nbsp;&nbsp; &nbsp;},500);<br />&nbsp; };<br /></span><span style="color: Olive;">&lt;/</span><span style="color: Green;">script</span><span style="color: Olive;">&gt;</span></div></div>
<p><span id="more-44"></span></p>
<p>测试结果：IE8点后退时会触发之前页面的window.onload事件，计数器回到初始状态重新计数；Opera9.6后退时不会触发前一个页面的window.onload事件，但定时器停止运行；其它浏览器后退时都不会触发前一个页面的window.onload事件，定时器会接着之前的状态继续计数。</p>
<p>结论：Firefox、Opera、Safari在这方面都做得比较人性化，完全的保留了页面unload时的状态，估计是直接从内存中读取缓存数据，所以后退速度相当快；其中Opera9.6会导致计数器停止，可能是个bug。IE在后退时则会回到最初状态，之前JS改变的DOM不复存在。</p>
<p>如果想让非IE浏览器退后时也能触发window.onload事件呢？<a href="http://www.firefoxanswer.com/firefox/672-firefoxanswer.html">这篇文章</a>提到了解决方案。其实就是在页面是加入：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">onunload</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(){}</span><span style="color: Gray;">;</span></div></div>
<p>经测试，此方法可行。对于其中的原理，<a href="http://hi.baidu.com/jkisjk">JK</a>给出了如下解释：</p>
<blockquote><p>FF／Safari等会努力做得很理想（完完全全的保持上次的unload时的信息），不过，如果他认为用户的代码（典型的是在onunload里）会破坏他的理想计划时，他就退一步，把“后退”当作“后退＋reload”。</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.qgy18.com/2008/09/browser_history_back/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
