简体   繁体   English

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

[英]Detecting Back Button/Hash Change in URL

I just set up my new homepage at http://ritter.vg . 我刚刚在http://ritter.vg上建立了新主页。 I'm using jQuery, but very minimally. 我正在使用jQuery,但是使用的次数很少。
It loads all the pages using AJAX - I have it set up to allow bookmarking by detecting the hash in the URL. 它使用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');

But I can't get the back and forward buttons to work. 但是我无法使前进和后退按钮起作用。

Is there a way to detect when the back button has been pressed (or detect when the hash changes) without using a setInterval loop? 有没有一种方法可以在不使用setInterval循环的情况下检测何时按下后退按钮(或检测哈希值何时变化)? When I tried those with .2 and 1 second timeouts, it pegged my CPU. 当我尝试使用.2和1秒超时的那些时,它挂住了我的CPU。

The answers here are all quite old. 这里的答案都是相当古老的。

In the HTML5 world, you should the use onpopstate event. 在HTML5世界中,您应该使用onpopstate事件。

window.onpopstate = function(event)
{
    alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};

Or: 要么:

window.addEventListener('popstate', function(event)
{
    alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
});

The latter snippet allows multiple event handlers to exist, whereas the former will replace any existing handler which may cause hard-to-find bugs. 后一个代码段允许存在多个事件处理程序,而前一个代码段将替换任何现有的可能导致难以发现错误的处理程序。

Use the jQuery hashchange event plugin instead. 请改用jQuery hashchange事件插件。 Regarding your full ajax navigation, try to have SEO friendly ajax . 关于您的完整Ajax导航,请尝试使用SEO友好的Ajax Otherwise your pages shown nothing in browsers with JavaScript limitations. 否则,您的页面在具有JavaScript限制的浏览器中什么也不会显示。

HTML5 has included a much better solution than using hashchange which is the HTML5 State Management APIs - https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history - they allow you to change the url of the page, without needing to use hashes! HTML5包含比使用hashchange更好的解决方案,后者是HTML5状态管理API- https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history-它们允许您更改页面的url,而无需使用哈希!

Though the HTML5 State Functionality is only available to HTML5 Browsers. 尽管HTML5状态功能仅可用于HTML5浏览器。 So you probably want to use something like History.js which provides a backwards compatible experience to HTML4 Browsers (via hashes, but still supports data and titles as well as the replaceState functionality). 因此,您可能想使用History.js之类的东西,它为HTML4浏览器提供了向后兼容的体验(通过散列,但仍支持数据和标题以及replaceState功能)。

You can read more about it here: https://github.com/browserstate/History.js 您可以在这里了解更多信息: https : //github.com/browserstate/History.js

Another great implementation is balupton's jQuery History which will use the native onhashchange event if it is supported by the browser, if not it will use an iframe or interval appropriately for the browser to ensure all the expected functionality is successfully emulated. balupton的jQuery History是另一个很好的实现,如果浏览器支持它,它将使用本机onhashchange事件;否则,它将为浏览器使用适当的iframe或间隔,以确保成功模拟所有预期功能。 It also provides a nice interface to bind to certain states. 它还提供了一个不错的接口来绑定到某些状态。

Another project worth noting as well is jQuery Ajaxy which is pretty much an extension for jQuery History to add ajax to the mix. 另一个值得注意的项目是jQuery Ajaxy ,它是jQuery History的扩展,可以将ajax添加到混合中。 As when you start using ajax with hashes it get's quite complicated ! 当您开始使用带有哈希值的ajax时,它变得相当复杂

Try simple & lightweight PathJS lib. 试试简单轻量的PathJS lib。

Simple example: 简单的例子:

Path.map("#/page").to(function(){
    alert('page!');
});

I do the following, if you want to use it then paste it in some where and set your handler code in locationHashChanged(qs) where commented, and then call changeHashValue(hashQuery) every time you load an ajax request. 如果您要使用它,请执行以下操作,然后将其粘贴到某个位置,并在注释的locationHashChanged(qs)中设置您的处理程序代码,然后在每次加载ajax请求时调用changeHashValue(hashQuery)。 Its not a quick-fix answer and there are none, so you will need to think about it and pass sensible hashQuery args (ie a=1&b=2) to changeHashValue(hashQuery) and then cater for each combination of said args in your locationHashChanged(qs) callback ... 它不是一个快速解决方案,也没有解决方案,因此您需要考虑一下,并将明智的hashQuery参数(即a = 1&b = 2)传递给changeHashValue(hashQuery),然后在locationHashChanged中满足上述参数的每种组合(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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM