28

我目前正在实现一个 JavaScript 库,该库跟踪地址栏中哈希部分的更改历史记录。这个想法是你可以在散列部分保留一个状态,然后使用后退按钮回到之前的状态。

在大多数最近的浏览器中,这是自动的,您只需轮询location.hash属性以进行更改(在 IE8 中您甚至不必这样做;您只需将函数附加到onhashchange事件。)

我想知道的是,有什么不同的方法来跟踪历史?我已经实现了经过测试可以在 Internet Explorer 6/7/8、Firefox 和 Chrome 中运行的功能,但是其他浏览器呢?以下是我目前保留历史记录的方式:

编辑:请参阅下面的答案,了解各种浏览器的演练。

4

5 回答 5

32

首先感谢回答的各位!=)

我现在做了更多的研究,我相信我对我的实施感到满意。以下是我的研究结果。

首先,我完成的Hash图书馆。它是一个没有依赖关系的独立库。它有两个功能:Hash.init(callback, iframe)Hash.go(newHash)。每当哈希以新哈希作为其第一个参数发生变化时调用回调函数,并将一个标志作为第二个参数,指示回调是由于初始状态(true)还是哈希的实际更改()而被调用false

Hash.js(麻省理工学院许可)

我还制作了一个 jQuery 插件,使其更易于使用。还添加了一个全局hashchange事件。请参阅源代码中的示例以了解如何使用它。

jquery.hash.js(麻省理工学院许可证)

要查看它们的使用情况,请转到我的 JavaScript“领域”页面:

Blixt 的 JavaScript 领域

互联网浏览器 8

平稳巡航!只需将其中一个onhashchange事件发送给window对象(使用attachEvent)并location.hash在事件处理程序中获取值。

用户是否单击带有哈希的链接,或者您是否以编程方式设置哈希都无关紧要;历史被完美保存。

Chrome、火狐、Safari 3+、Opera 8+

平稳巡航!只需使用和函数轮询对location.hash属性的更改。setInterval

历史完美运行。对于 Opera,我设置history.navigationMode'compatible'. 老实说,我不确定它是做什么的,我是根据 YUI 代码中的评论推荐的。

注意:Opera 需要一些额外的测试,但到目前为止它对我来说效果很好。

惊喜怪癖奖金!(可以吗?!)事实证明,Firefox(仅在 3.5+ 中确认)解码了该location.hash属性,因此这可以触发hashchange两次事件(首先是编码版本,然后是未编码版本。)我的有一个新版本Hash.js 库通过使用属性来考虑这一点location.href(由 Aaron Ogle 提供的更改。)

互联网浏览器 6、7

现在它变得更糟了。旧 Internet Explorer 版本中的导航历史会忽略哈希更改。为了解决这个问题,普遍接受的解决方案是创建一个iframe并将其内容设置为新的哈希值。这会在导航历史记录中创建一个新条目。当用户返回时,这会将 的内容更改为iframe之前的内容。通过检测内容的变化,可以获取并设置为活动哈希。

location.hash仍然需要检查属性的更改才能手动更改当前地址。不过,请注意我在下面提到的怪癖。

虽然这个解决方案似乎是最好的解决方案,但它在 Internet Explorer 6 中仍然不完美,这对于后退/前进按钮有点奇怪。不过,Internet Explorer 7 运行良好。

惊喜怪癖奖金 #1!在 Internet Explorer 6 中,只要哈希中有问号,就会将其提取并放入 location.search 属性中!它已从 location.hash 属性中删除。但是,如果有一个真正的查询字符串, location.search 它将包含那个,并且您只能通过解析 location.href 属性来获得整个真正的哈希值。

惊喜怪癖奖金 #2!如果设置了该属性, 则将从(and ) 属性中删除location.search 任何后续字符。 在 Internet Explorer 6 中,这意味着只要路径或哈希中有问号,您就会遇到这种怪癖。在 Internet Explorer 7 中,仅当路径中有问号时才会出现此问题。您不只是喜欢 Internet Explorer 中的一致性吗?# location.href location.hash

惊喜怪癖奖金 #3!如果页面上的另一个元素具有与哈希值相同的 id,则该哈希将完全弄乱历史记录。因此,经验法则是避免与页面上的任何元素具有相同 id 的哈希值。如果哈希是动态生成的并且可能与 id 冲突,请考虑使用前缀/后缀。

其它浏览器

除非您拥有非同寻常的用户群,否则您不需要支持更多浏览器。上面未列出的浏览器属于 <1% 的使用类别。

于 2009-07-07T11:32:14.513 回答
3

根据您为此付出的努力,我假设您已经看过YUI Browser History Manager,但以防万一...

他们很好地描述了他们的实现,我发现他们的源代码非常可读。

这是它对 Opera 的评价

* location.hash is a bit buggy on Opera. I have seen instances where
* navigating the history using the back/forward buttons, and hence
* changing the URL, would not change location.hash. That's ok, the
* implementation of an equivalent is trivial ... more below

搜索源代码,我还发现了一些适用于 Safari 1.x 和 2.0 的内容。看来你会对它感兴趣。

希望有帮助。

于 2009-07-04T15:55:16.787 回答
1

我不确定我是否完全理解您的需求,但我使用了真正简单的历史库 ( http://code.google.com/p/reallysimplehistory/ ) 来实现类似的东西。你可以在这里看到它:http ://whiteoak.sourceforge.net/

于 2009-07-03T09:27:39.510 回答
0

我在任何地方都没有看到任何关于我要说的内容,所以我想我会分享一下,看看它是多么的常识。

在 IE 中(仅在 IE7 中验证),当屏幕上有一个 id 等于散列的页面元素时,带有散列的历史记录可以正常工作。例如,想想 wiki 页面上的目录 (TOC)。TOC 中的每个链接都链接到页面某处的 id 或锚名称元素的散列:

<div id="TOC">
<a id="SampleHeaderLink" href="#SampleHeader">Sample Header</a>
</div>

<h2 id="SampleHeader">Sample Header</a>

所以当点击 SampleHeaderLink 时,IE 浏览器默认设置是导航到 SampleHeader 并在历史记录中注册状态。使用后退按钮和前进按钮按预期工作。

但是,如果页面上不存在 SampleHeader div,则浏览器只会注册 url 更改,但不会为其创建新状态。

同样,这仅在 IE7 中得到验证。而且我不知道这些信息有多普遍,但是当我在自己的应用程序中浏览以解决这个问题时,我从未发现任何相关信息。

于 2011-02-28T20:34:50.120 回答
-1

GWT 提供历史管理。它也是他们 MVP 框架的一个组成部分。他们还通过地点和活动增强了历史 API。

于 2011-08-08T17:00:01.687 回答