保持JavaScript中哈希/锚点更改的历史记录

时间:2009-07-03 09:12:15

标签: javascript fragment-identifier

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

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

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

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

5 个答案:

答案 0 :(得分:32)

首先,感谢你们的回答! =)

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

首先,my finished Hash library。它是一个没有依赖关系的独立库。它有两个功能:Hash.init(callback, iframe)Hash.go(newHash)。每当散列以新散列作为其第一个参数而更改时调用回调函数,并且作为其第二个参数,指示是否由于初始状态(true)或散列的实际更改而调用回调的标志( false)。

  

Hash.js(麻省理工学院执照)

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

  

jquery.hash.js(麻省理工学院执照)

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

  

Blixt's JavaScript realm

Internet Explorer 8

Smooooth cruisin'!只需将onhashchange个事件发送到window对象(使用attachEvent),然后在事件处理程序中获取location.hash值。

如果用户单击带有散列的链接,或者以编程方式设置散列,则无关紧要;历史是完美的。

Chrome,Firefox,Safari 3 +,Opera 8 +

光滑的cruisin'!只需使用location.hash和函数调查setInterval属性的更改。

历史非常有效。对于Opera,我将history.navigationMode设置为'compatible'。说实话,我不确定它是做什么的,我是根据YUI代码中的评论推荐的。

注意 :Opera需要一些额外的测试,但到目前为止它对我来说还不错。

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

Internet Explorer 6,7

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

手动更改当前地址仍需要检查location.hash属性的更改。但要注意我在下面提到的怪癖。

虽然这个解决方案似乎是最好的解决方案,但它仍然不是完美的Internet Explorer 6,这对后退/前进按钮有点古怪。不过,Internet Explorer 7工作正常。

惊喜quirk bonus#1! 在Internet Explorer 6中,只要哈希中有问号,就会将其解压缩并放入 location.search 属性!它已从 location.hash 属性中删除。但是,如果存在真正的查询字符串,则 location.search 将包含该字符串,并且您只能通过解析 {{来获取整个真正的哈希值。 1}} property。

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

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

其他浏览器

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

答案 1 :(得分: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& amp; 2.0也。好像你对它感兴趣。

希望有所帮助。

答案 2 :(得分:1)

我不确定我是否完全理解您的需求,但我使用了Really Simple History库(http://code.google.com/p/reallysimplehistory/)来实现类似的功能。你可以在这里看到它:http://whiteoak.sourceforge.net/

答案 3 :(得分:0)

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

在IE中(仅在IE7中验证),当屏幕上的页面元素具有等于散列的id时,具有散列的历史记录正常工作。例如,想一想维基页面上的目录(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中得到验证。而且我不知道这些信息是多么常识,但是当我在我自己的应用程序中浏览修复这个问题时,我从未发现任何相关内容。

答案 4 :(得分:-1)

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