我正在使用Ajax和hash实现导航。
有没有一种方法可以检查window.location.hash
是否发生了变化,例如:
http://example.com/blah#123 变为 http://example.com/blah#456
如果是在文档加载时检查,它是有效的。
但如果我基于#hash进行导航,在浏览器上按下返回按钮时它不起作用(所以我从blah#456跳转到blah#123)。
地址栏里会显示,但我无法用JavaScript捕获它。
我正在使用Ajax和hash实现导航。
有没有一种方法可以检查window.location.hash
是否发生了变化,例如:
http://example.com/blah#123 变为 http://example.com/blah#456
如果是在文档加载时检查,它是有效的。
但如果我基于#hash进行导航,在浏览器上按下返回按钮时它不起作用(所以我从blah#456跳转到blah#123)。
地址栏里会显示,但我无法用JavaScript捕获它。
$(window).on('hashchange', function() {
//.. work ..
});
优点在于你可以编写不必考虑hashchange支持的代码,然而你需要使用一些魔法,形式为一个比较不为人知的jQuery功能jQuery特殊事件。
使用此功能,您基本上可以为任何事件运行一些设置代码,第一次尝试以任何方式使用该事件时(例如绑定到该事件)。
在此设置代码中,您可以检查本机浏览器支持情况,如果浏览器没有本地实现这个支持,则可以设置单个计时器来轮询更改并触发jQuery事件。
这完全解除了您的代码需要理解此支持问题的束缚,实现此类特殊事件是微不足道的(获取简单的98%工作版本),但为什么要这样做,当别人已经有了呢。
hashchange
事件,而Safari(稳定版)尚未。 - jholsterhashchange
事件现在得到广泛支持:http://caniuse.com/#search=hash - PaysteyHTML5指定了一个hashchange
事件。这个事件现在被所有现代浏览器支持。支持该事件的浏览器版本如下:
hashchange
事件在浏览器地址栏中的URL哈希值发生变化时触发。当用户点击页面上的锚链接或通过JavaScript代码修改URL的哈希值时,该事件将被触发。使用window.onhashchange
属性可以为该事件添加事件处理程序函数。通过这种方式,您可以编写适当的JavaScript代码来响应哈希值的更改,并对页面进行相应的操作。然而,请注意,某些旧版浏览器可能不支持此事件。因此,在编写使用该事件的代码时,请确保您的代码具有适当的浏览器兼容性。 - lele1cif
语句将返回true(对于窗口中的"onhashchange"),但是window.onhashchange
永远不会触发,因此最好在Internet Explorer的所有版本中存储哈希并每隔100毫秒检查它是否已更改。 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/
我在一个React应用程序中使用这个功能,根据用户所在的视图来显示不同的URL参数。
我使用了哈希参数进行观察。
window.addEventListener('hashchange', doSomethingWithChangeFunction);
那么
function doSomethingWithChangeFunction () {
let urlParam = window.location.hash; // Get new hash value
// ... Do something with new hash value
};
它非常有效。它可以与前进和后退浏览器按钮一起使用,也可以在浏览器历史记录中使用。
在处理IE浏览器中的历史记录和window.location.hash时,有很多技巧:
正如原问题所述,如果您从a.html#b转到a.html#c,然后点击“后退”按钮,浏览器不知道页面已更改。让我用一个例子来说明:无论您在a.html#b还是a.html#c中,window.location.href都将是'a.html#c'。
实际上,只有当页面中之前存在元素'<a name="#b">'和'<a name="#c">'时,a.html#b和a.html#c才会被存储在历史记录中。
但是,如果您在页面中放置一个iframe,在该iframe中从a.html#b导航到a.html#c,然后点击“后退”按钮,iframe.contentWindow.document.location.href会按预期更改。
如果您在代码中使用'document.domain=something',则无法访问iframe.contentWindow.document.open()(许多历史记录管理器都这样做)。
我知道这不是真正的回答,但也许IE历史记录笔记对某些人有用。
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;
watch
应用于拥有正在更改且您想要观察的属性的对象。 - gion_13var 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);
就是这样...现在,每当您点击后退或前进按钮时,页面将根据新的哈希值重新加载。
另一个很棒的实现是jQuery History,如果浏览器支持本机onhashchange事件,则会使用它,否则它将适当地使用iframe或间隔来确保成功模拟所有预期功能。它还提供了一个漂亮的接口来绑定到某些状态。
另一个值得注意的项目是jQuery Ajaxy,它基本上是jQuery History的扩展,添加了ajax。因为当您开始在哈希中使用ajax时,它变得相当复杂!