[英]How can I detect changes in location hash?
我正在使用 Ajax 和 hash 进行导航。
有没有办法检查window.location.hash
是否像这样更改?
http://example.com/blah #123到http://example.com/blah #456
如果我在加载文档时检查它,它就会工作。
但是,如果我有基于#hash 的导航,当我按下浏览器上的后退按钮时它就不起作用(所以我从 blah#456 跳到 blah#123)。
它显示在地址框内,但我无法用 JavaScript 捕获它。
真正做到这一点的唯一方法(以及 'reallysimplehistory' 如何做到这一点)是通过设置一个间隔来不断检查当前的哈希值,并将其与之前的哈希值进行比较,我们这样做并让订阅者订阅更改的如果散列更改,我们会触发事件......它并不完美,但浏览器本身并不支持此事件。
更新以保持此答案新鲜:
如果您正在使用 jQuery(现在对于大多数人来说应该是基础),那么一个不错的解决方案是使用 jQuery 为您提供的抽象,通过使用其事件系统来侦听 window 对象上的 hashchange 事件。
$(window).on('hashchange', function() {
//.. work ..
});
这里的好处是你可以编写甚至不需要担心 hashchange 支持的代码,但是你确实需要做一些魔术,以一种鲜为人知的 jQuery 特性jQuery special events 的形式。
使用此功能,您基本上可以为任何事件运行一些设置代码,第一次有人尝试以任何方式使用该事件(例如绑定到事件)。
在此设置代码中,您可以检查本机浏览器支持,如果浏览器未本机实现此功能,您可以设置一个计时器来轮询更改,并触发 jQuery 事件。
这完全解除了你的代码需要理解这个支持问题的束缚,这种特殊事件的实现是微不足道的(获得一个简单的 98% 工作版本),但是当其他人已经有了.
HTML5 指定了一个hashchange
事件。 现在所有现代浏览器都支持此事件。 在以下浏览器版本中添加了支持:
请注意,在 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 。
Ben Alman 有一个很好的 jQuery 插件来处理这个问题: http : //benalman.com/projects/jquery-hashchange-plugin/
如果你不使用 jQuery,它可能是一个有趣的解剖参考。
您可以在“window.location”对象的“hash”属性上轻松实现观察者(“watch”方法)。
Firefox 有自己的实现来观察 object 的变化,但是如果你使用一些其他的实现(比如在 JavaScript 中观察对象属性的变化) - 对于其他浏览器,那就行了。
代码如下所示:
window.location.watch(
'hash',
function(id,oldVal,newVal){
console.log("the window's hash value has changed from "+oldval+" to "+newVal);
}
);
然后你可以测试一下:
var myHashLink = "home";
window.location = window.location + "#" + myHashLink;
当然,这会触发您的观察者功能。
我在 React 应用程序中使用它来使 URL 显示不同的参数,具体取决于用户所在的视图。
我观看了哈希参数使用
window.addEventListener('hashchange', doSomethingWithChangeFunction());
然后
doSomethingWithChangeFunction () {
// Get new hash value
let urlParam = window.location.hash;
// Do something with new hash value
};
工作得很好,使用前进和后退浏览器按钮以及浏览器历史记录。
一个不错的实现可以在http://code.google.com/p/reallysimplehistory/找到。 它唯一(但也是)的问题和错误是:在 Internet Explorer 中,手动修改位置哈希将重置整个历史堆栈(这是浏览器问题,无法解决)。
请注意,Internet Explorer 8 确实支持“hashchange”事件,并且由于它正在成为 HTML5 的一部分,您可能希望其他浏览器能够赶上。
另一个很棒的实现是jQuery History ,如果浏览器支持它,它将使用本机 onhashchange 事件,如果不支持,它将为浏览器适当地使用 iframe 或间隔,以确保成功模拟所有预期的功能。 它还提供了一个很好的界面来绑定到某些状态。
另一个值得注意的项目是jQuery Ajaxy ,它几乎是 jQuery History 的扩展,用于将 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);
就是这样......现在,无论何时您按下后退或前进按钮,页面都会根据新的哈希值重新加载。
简短的示例单击按钮进行更改 hash
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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.