检测 URL 中的后退按钮/哈希更改

Detecting Back Button/Hash Change in URL

提问人:Tom Ritter 提问时间:10/6/2008 最后编辑:baluptonTom Ritter 更新时间:12/20/2013 访问量:113720

问:

我刚刚在 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 挂钩。

javascript ajax 导航 fragment-identifier hashchange

评论

3赞 balupton 3/7/2011
而不是以 HTML4 事件为目标;现在有 HTML5 History API 可以超级播种它。这是一个很好的参考hashchange

答:

31赞 Komang 10/6/2008 #1

请改用 jQuery hashchange 事件插件。关于你的完整ajax导航,尝试使用SEO友好的ajax。否则,您的页面在具有 JavaScript 限制的浏览器中不会显示任何内容。

评论

0赞 Drew Noakes 4/3/2013
如今,您可以使用 HTML5 API 来实现此目的。
12赞 micahwittman 2/4/2010 #2

jQuery BBQ(后退按钮和查询库)

一个高质量的基于哈希的浏览器历史插件,在撰写本文时非常最新(2010 年 1 月 26 日)(jQuery 1.4.1)。

2赞 balupton 8/29/2010 #3

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

另一个值得注意的项目是 jQuery Ajaxy,它几乎是 jQuery History 的扩展,用于将 ajax 添加到组合中。因为当你开始使用带有哈希的ajax时,它变得非常复杂

11赞 balupton 1/30/2011 #4

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

1赞 Eugene Kerner 4/19/2011 #5

我执行以下操作,如果您想使用它,请将其粘贴到某个位置,并在注释的 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();

评论

0赞 Chaim 6/3/2011
使用它只是为了在使用锚点导航我的页面时更改活动链接。
1赞 Nikita Koksharov 4/20/2012 #6

尝试简单和轻量级的 PathJS 库。

简单示例:

Path.map("#/page").to(function(){
    alert('page!');
});
50赞 Drew Noakes 12/6/2012 #7

这里的答案都已经很老了。

在 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 的现有处理程序。