在 – window.location.hash – 更改?

我正在使用Ajax和哈希导航。

有没有办法检查window.location.hash是否像这样改变?

http://example.com/blah#123到http://example.com/blah#456

如果我在文档加载时检查它,它将起作用。

但是,如果我有基于#hash的导航,当我按下浏览器上的后退button时不起作用(所以我从#456跳转到#123)。

它显示在地址框内,但我无法用JavaScript来捕捉它。

真正做到这一点的唯一方法就是通过设置一个间隔来检查当前的散列,并与之前的情况进行比较,我们这样做并让订阅者订阅一个更改事件,如果哈希变化,我们开火..它不完美,但浏览器本身并不支持这个事件。


更新以保持这个答案新鲜:

如果你正在使用jQuery(现在应该是大多数基础),那么一个很好的解决scheme就是使用jQuery为你提供的抽象,通过它的事件系统来监听窗口对象上的hashchange事件。

 $(window).on('hashchange', function() { //.. work .. }); 

这里的好处是你可以编写不需要甚至担心hashchange支持的代码,但是你需要做一些神奇的事情,以一种稍微不为人知的jQuery特性jQuery特殊事件的forms 。

有了这个function,你基本上可以为任何事件运行一些设置代码,第一次有人尝试以任何方式使用事件(比如绑定到事件)。

在这个设置代码中,你可以检查本机浏览器的支持,如果浏览器本身不实现这一点,你可以设置一个计时器来轮询更改,并触发jQuery事件。

这完全解开你的代码从了解这个支持问题,这种特殊事件的实现是微不足道的(得到一个简单的98%的工作版本),但为什么当别人已经这样做了 。

HTML5 指定了一个hashchange事件 。 现在所有的浏览器都支持这个事件。 在以下浏览器版本中添加了支持:

  • Internet Explorer 8
  • Firefox 3.6
  • Chrome 5
  • Safari 5
  • Opera 10.6

请注意,在Internet Explorer 7和Internet Explorer 9的情况下, if语句会显示true(对于windows中的“onhashchange”),但window.onhashchange永远不会触发,因此最好每隔100毫秒存储一次散列值并检查它已被更改或不是所有版本的Internet Explorer。

  if (("onhashchange" in window) && !($.browser.msie)) { window.onhashchange = function () { alert(window.location.hash); } // Or $(window).bind( 'hashchange',function(e) { // alert(window.location.hash); // }); } else { var prevHash = window.location.hash; window.setInterval(function () { if (window.location.hash != prevHash) { prevHash = window.location.hash; alert(window.location.hash); } }, 100); } 

编辑 – 由于jQuery 1.9,不支持$.browser.msie 。 资料来源: http : //api.jquery.com/jquery.browser/

在IE浏览器中有很多处理History和window.location.hash的技巧:

  • 正如原来的问题所说,如果你从页面a.html#b到a.html#c,然后点击后退button,浏览器不知道页面已经改变。 让我用一个例子来说:window.location.href将是'a.html#c',不pipe你是在a.html#b还是a.html#c。

  • 实际上, 只有当元素的<a name="#b">'和'<a name="#c">'存在于页面中时, 才会将 a.html#b和a.html#c存储在历史logging中。

  • 但是,如果在页面中放置iframe,则从该iframe中的a.html#b导航到a.html#c,然后点击后退button,iframe.contentWindow.document.location.href将按预期更改。

  • 如果您在代码中使用“document.domain = something ”,那么您将无法访问iframe.contentWindow.document.open()(许多历史loggingpipe理器会这样做)

我知道这不是一个真正的回应,但也许IE历史笔记是有用的人。

Firefox从3.6开始就有一个onhashchange事件。 请参阅window.onhashchange

本·阿尔曼有一个伟大的jQuery插件来处理这个问题: http : //benalman.com/projects/jquery-hashchange-plugin/

如果你不使用jQuery,这可能是一个有趣的解剖参考。

你可以很容易地在“window.location”对象的“hash”属性上实现一个观察者(“watch”方法)。

Firefox有自己的实现来监视对象的变化 ,但是如果你使用其他一些实现(例如监视JavaScript中的对象属性变化 ) – 对于其他浏览器来说,这将会起到一些作用。

代码将如下所示:

 window.location.watch( 'hash', function(id,oldVal,newVal){ console.log("the window's hash value has changed from "+oldval+" to "+newVal); } ); 

那么你可以testing它:

 var myHashLink = "home"; window.location = window.location + "#" + myHashLink; 

当然这会触发你的观察员function。

http://code.google.com/p/reallysimplehistory/上可以find体面的实现。; 唯一的(也是)问题和错误是:在Internet Explorer中手动修改位置哈希将重置整个历史堆栈(这是一个浏览器问题,它不能被解决)。

请注意,Internet Explorer 8确实支持“hashchange”事件,并且由于它正在成为HTML5的一部分,所以您可能希望其他浏览器能够赶上。

另一个很好的实现是jQuery History ,如果它被浏览器支持,将使用本地onhashchange事件,如果不是,它将使用适当的iframe或时间间隔适当的浏览器,以确保所有预期的function被成功模拟。 它还提供了一个很好的界面来绑定到某些状态。

另一个值得注意的项目是jQuery Ajaxy ,它几乎是jQuery History的扩展,可以添加ajax。 当你开始使用哈希值的时候,它变得相当复杂 !

 var page_url = 'http://www.yoursite.com/'; // full path leading up to hash; var current_url_w_hash = page_url + window.location.hash; // now you might have something like: http://www.yoursite.com/#123 function TrackHash() { if (document.location != page_url + current_url_w_hash) { window.location = document.location; } return false; } var RunTabs = setInterval(TrackHash, 200); 

就是这样……现在,无论何时按下后退或前进button,页面都将按照新的散列值重新加载。

我一直在为我的客户端路由使用path.js。 我发现它非常简洁和轻量级(它也被发布到NPM),并利用基于哈希的导航。

path.js NPM

path.js GitHub

我使用了一个jQuery插件HUtil ,并在其上面写了一个YUI历史logging。

检查一下。 如果你需要帮助,我可以帮忙。