我如何检测位置哈希的变化?

我使用Ajax和哈希导航。

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

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

如果我在文件加载时检查它,它就会工作。

但如果我有#哈希导航,它不工作时,我按浏览器上的后退按钮(所以我从blah#456跳转到blah#123)。

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

422269 次浏览

真正做到这一点的唯一方法(也是'reallysimplehistory'如何做到这一点的),是通过设置一个间隔来不断检查当前哈希,并将其与之前的哈希进行比较,我们这样做,并让订阅者订阅一个发生变化的事件,如果哈希发生变化。它并不完美,但是浏览器本身并不支持这个事件。


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

如果您正在使用jQuery(对于大多数人来说,这应该是基本的),那么一个很好的解决方案是使用jQuery提供的抽象,通过使用它的事件系统来侦听窗口对象上的hashchange事件。

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

这里的好处是,您可以编写甚至不需要担心hashchange支持的代码,但是您确实需要做一些神奇的事情,以不太为人所知的jQuery特性jQuery特殊事件的形式。

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

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

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

HTML5 # EYZ1。这个事件现在是所有现代浏览器都支持。以下浏览器版本增加了支持:

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

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

  • 正如最初的问题所说,如果你从a.html#b页转到a.html#c页,然后点击返回按钮,浏览器不知道页面已经更改。让我用一个例子来说明:window.location.href将是'a.html#c',无论你是在a.html#b还是a.html#c中。

  • 实际上,如果元素'<a name="#b">'和'<a name="#c">'之前在页面中存在,a.html#b和a.html#c被存储在history 中。

  • 然而,如果你把一个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事件。看到# EYZ0。

另一个很好的实现是jQuery的历史,如果浏览器支持它,它将使用本机onhashchange事件,如果不支持,它将使用浏览器适当的iframe或interval,以确保所有预期的功能都被成功模拟。它还提供了一个很好的接口来绑定某些状态。

另一个值得注意的项目是jQuery Ajaxy,它几乎是jQuery历史的一个扩展,将ajax添加到混合。当你开始使用带有哈希的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);

就是这样……现在,无论何时点击后退或前进按钮,页面都会根据新的哈希值重新加载。

注意,对于internetexplorer7和internetexplorer9, if语句将返回true(对于windows中的"onhashchange"),但window.onhashchange语句永远不会触发,因此最好存储哈希值,并在每100毫秒后检查它是否为所有版本的internetexplorer7和internetexplorer9更改。

    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);
}
< p >编辑- 从jQuery 1.9开始,$.browser.msie就不支持了。来源:# EYZ1 < / p >

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

path.js npm .js

path.js GitHub . GitHub

我在一个react应用程序中使用这个,使URL显示不同的参数,取决于用户所处的视图。

我看了哈希参数使用

window.addEventListener('hashchange', doSomethingWithChangeFunction);

然后

function doSomethingWithChangeFunction () {
let urlParam = window.location.hash; // Get new hash value
    

// ... Do something with new hash value
};

工作了一个待遇,工作与前进和后退浏览器按钮,也在浏览器历史记录。

简短的例子 点击按钮更改哈希

window.onhashchange = () => console.log(`Hash changed -> ${window.location.hash}`)
<button onclick="window.location.hash=Math.random()">hash to Math.Random</button>


<button onclick="window.location.hash='ABC'">Hash to ABC</button>


<button onclick="window.location.hash='XYZ'">Hash to XYZ</button>