在 - window.location.hash - 改变?

IT技术 javascript ajax dom-events fragment-identifier hashchange
2021-01-30 04:56:16

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

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

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

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

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

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

6个回答

真正做到这一点的唯一方法(以及“reallysimplehistory”如何做到这一点),是通过设置一个间隔来不断检查当前的哈希值,并将其与之前的值进行比较,我们这样做并让订阅者订阅更改的如果散列更改,我们会触发事件......它并不完美,但浏览器本身并不支持此事件。


更新以保持此答案新鲜:

如果您正在使用 jQuery(现在对于大多数人来说应该是基础),那么一个不错的解决方案是使用 jQuery 为您提供的抽象,通过使用其事件系统来侦听 window 对象上的 hashchange 事件。

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

这里的好处是您可以编写甚至不需要担心 hashchange 支持的代码,但是您确实需要以一种鲜为人知的 jQuery 特性jQuery special events 的形式做一些魔术

使用此功能,您基本上可以为任何事件运行一些设置代码,第一次有人尝试以任何方式使用该事件(例如绑定到事件)。

在此设置代码中,您可以检查本机浏览器支持,如果浏览器未本机实现此功能,您可以设置一个计时器来轮询更改,并触发 jQuery 事件。

这完全解除了你的代码需要理解这个支持问题的束缚,这种特殊事件的实现是微不足道的(获得一个简单的 98% 工作版本),但是为什么在其他人已经.

在撰写本文时,WebKit 也会触发hashchange事件,而 Safari(稳定版)还没有。
2021-03-11 04:56:16
只是为了添加另一个更新,该hashchange事件现在得到广泛支持:caniuse.com/#search=hash
2021-03-15 04:56:16
最新的 Firefox 版本(3.6 alpha)现在也支持原生哈希更改事件:developer.mozilla.org/en/DOM/window.onhashchange 这个事件当然值得检查,但注意 IE8 会告诉你这个事件当它在 IE7 兼容模式下运行时存在.. 遗憾的是该事件没有触发.. 您需要检查该事件并且浏览器似乎不是 IE7.. 叹气(或尝试触发事件使用 IE 的 fireEvent 方法)。
2021-03-28 04:56:16
我是唯一一个认为未经请求的 jQuery 答案很痛苦的人吗?
2021-03-30 04:56:16
此答案现已弃用
2021-03-30 04:56:16

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

  • 浏览器 8
  • 火狐 3.6
  • 铬 5
  • 野生动物园 5
  • 歌剧 10.6
更新:截至 2011 年 6 月,FF 5、Safari 5 和 Chrome 12 支持此事件。
2021-03-11 04:56:16
用法: window.onhashchange = function() { doYourStuff(); }
2021-03-15 04:56:16
2021-03-19 04:56:16
@everybody,无需在评论部分继续附加答案——这就是“编辑”按钮的用途。:)
2021-03-20 04:56:16
这是hashchange 的 CanIUse 页面这是quirksmode上的hashchangeIE 支持在区分大小写方面存在问题。
2021-03-30 04:56:16

请注意,在 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,然后点击后退按钮,浏览器不会知道该页面已更改。让我举个例子:window.location.href 将是'a.html#c',无论你是在a.html#b 还是a.html#c。

  • 实际上,a.html#b 和 a.html#c在页面中先前存在元素 '<a name="#b">' 和 '<a name="#c">'时才存储在历史记录中。

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

  • 如果您在代码中使用 'document.domain= something ',则无法访问 iframe.contentWindow.document.open()'(许多历史记录管理器都这样做)

我知道这不是真正的回应,但也许 IE-History 注释对某些人有用。

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