提问人:Tom Ritter 提问时间:10/6/2008 最后编辑:baluptonTom Ritter 更新时间:12/20/2013 访问量:113720
检测 URL 中的后退按钮/哈希更改
Detecting Back Button/Hash Change in URL
问:
我刚刚在 http://ritter.vg 设置了我的新主页。我正在使用jQuery,但非常少。
它使用 AJAX 加载所有页面 - 我将其设置为通过检测 URL 中的哈希值来允许书签。
//general functions
function getUrl(u) {
return u + '.html';
}
function loadURL(u) {
$.get(getUrl(u), function(r){
$('#main').html(r);
}
);
}
//allows bookmarking
var hash = new String(document.location).indexOf("#");
if(hash > 0)
{
page = new String(document.location).substring(hash + 1);
if(page.length > 1)
loadURL(page);
else
loadURL('news');
}
else
loadURL('news');
但是我无法让后退和前进按钮工作。
有没有办法在不使用 setInterval 循环的情况下检测何时按下后退按钮(或检测哈希值何时更改)?当我尝试那些具有 .2 和 1 秒超时,它与我的 CPU 挂钩。
答:
请改用 jQuery hashchange 事件插件。关于你的完整ajax导航,尝试使用SEO友好的ajax。否则,您的页面在具有 JavaScript 限制的浏览器中不会显示任何内容。
评论
一个高质量的基于哈希的浏览器历史插件,在撰写本文时非常最新(2010 年 1 月 26 日)(jQuery 1.4.1)。
另一个很棒的实现是 balupton 的 jQuery History,如果浏览器支持它,它将使用本机 onhashchange 事件,如果不支持,它将为浏览器适当地使用 iframe 或间隔,以确保成功模拟所有预期的功能。它还提供了一个很好的接口来绑定到某些状态。
另一个值得注意的项目是 jQuery Ajaxy,它几乎是 jQuery History 的扩展,用于将 ajax 添加到组合中。因为当你开始使用带有哈希的ajax时,它变得非常复杂!
HTML5 包含了一个比使用 hashchange 更好的解决方案,即 HTML5 状态管理 API - https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history - 它们允许您更改页面的 URL,而无需使用哈希!
虽然 HTML5 状态功能仅适用于 HTML5 浏览器。因此,您可能希望使用像 History.js 这样的东西,它为 HTML4 浏览器提供了向后兼容的体验(通过哈希,但仍然支持数据和标题以及 replaceState 功能)。
您可以在此处阅读有关它的更多信息: https://github.com/browserstate/History.js
我执行以下操作,如果您想使用它,请将其粘贴到某个位置,并在注释的 locationHashChanged(qs) 中设置处理程序代码,然后在每次加载 ajax 请求时调用 changeHashValue(hashQuery)。 它不是一个快速修复的答案,也没有,所以你需要考虑它并将合理的hashQuery参数(即a=1&b=2)传递给changeHashValue(hashQuery),然后在你的位置HashChanged(qs)回调中满足所述参数的每个组合......
// Add code below ...
function locationHashChanged(qs)
{
var q = parseQs(qs);
// ADD SOME CODE HERE TO LOAD YOUR PAGE ELEMS AS PER q !!
// YOU SHOULD CATER FOR EACH hashQuery ATTRS COMBINATION
// THAT IS PASSED TO changeHashValue(hashQuery)
}
// CALL THIS FROM YOUR AJAX LOAD CODE EACH LOAD ...
function changeHashValue(hashQuery)
{
stopHashListener();
hashValue = hashQuery;
location.hash = hashQuery;
startHashListener();
}
// AND DONT WORRY ABOUT ANYTHING BELOW ...
function checkIfHashChanged()
{
var hashQuery = getHashQuery();
if (hashQuery == hashValue)
return;
hashValue = hashQuery;
locationHashChanged(hashQuery);
}
function parseQs(qs)
{
var q = {};
var pairs = qs.split('&');
for (var idx in pairs) {
var arg = pairs[idx].split('=');
q[arg[0]] = arg[1];
}
return q;
}
function startHashListener()
{
hashListener = setInterval(checkIfHashChanged, 1000);
}
function stopHashListener()
{
if (hashListener != null)
clearInterval(hashListener);
hashListener = null;
}
function getHashQuery()
{
return location.hash.replace(/^#/, '');
}
var hashListener = null;
var hashValue = '';//getHashQuery();
startHashListener();
评论
尝试简单和轻量级的 PathJS 库。
简单示例:
Path.map("#/page").to(function(){
alert('page!');
});
这里的答案都已经很老了。
在 HTML5 世界中,您应该使用 onpopstate
事件。
window.onpopstate = function(event)
{
alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
艺术
window.addEventListener('popstate', function(event)
{
alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
});
后一个代码片段允许存在多个事件处理程序,而前者将替换任何可能导致难以找到的 bug 的现有处理程序。
评论
hashchange