如何检测JavaScript中的URL更改

我怎样才能检查一个URL在JavaScript中已经改变? 例如,像GitHub这样使用AJAX的网站,会在#符号后附加页面信息来创build一个唯一的URL,而不用重新加载页面。 检测此url是否更改的最佳方法是什么?

  • 是否再次onload事件?
  • 有没有URL的事件处理程序?
  • 还是必须每秒检查一次URL以检测更改?

在现代浏览器(IE8 +,FF3.6 +,Chrome)中,您只能在window上聆听hashchange事件。

在一些旧的浏览器中,您需要一个定时器来持续检查location.hash 。 如果你使用的是jQuery,那么就有一个插件 。

使用jQuery(和一个插件),你可以做

 $(window).bind('hashchange', function() { /* things */ }); 

http://benalman.com/projects/jquery-hashchange-plugin/

否则是的,你将不得不使用setInterval并检查散列事件(window.location.hash)中的更改

更新! 一个简单的草案

 function hashHandler(){ this.oldHash = window.location.hash; this.Check; var that = this; var detect = function(){ if(that.oldHash!=window.location.hash){ alert("HASH CHANGED - new has" + window.location.hash); that.oldHash = window.location.hash; } }; this.Check = setInterval(function(){ detect() }, 100); } var hashDetection = new hashHandler(); 

使用这个代码

 window.onhashchange = function() { //code } 

与jQuery

 $(window).bind('hashchange', function() { //code }); 

编辑经过一番研究:

不知何故,似乎我被Mozilla文档中的文档所迷惑。 在代码中调用pushState()replaceState()时, 不会触发 popstate事件(及其onpopstatecallback函数)。 因此,原始答案并不适用于所有情况。

但有一种方法可以通过按照@ alpha123的方式来修改这些函数 :

 var pushState = history.pushState; history.pushState = function () { pushState.apply(history, arguments); fireEvents('pushState', arguments); // Some event-handling function }; 

原始答案

鉴于这个问题的标题是“ 如何检测URL变化 ”的答案,当你想知道完整path何时改变(而不仅仅是哈希锚),你可以听popstate事件:

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

在Mozilla文档中引用popstate

目前(2017年1月),全球92%的浏览器支持popstate 。

添加一个哈希变化事件监听器!

 window.addEventListener('hashchange', function(e){console.log('hash changed')}); 

或者,要收听所有url更改:

 window.addEventListener('popstate', function(e){console.log('url changed')}); 

这比下面的代码更好,因为在window.onhashchange中只有一件事情可以存在,你可能会覆盖别人的代码。

 // Bad code example window.onhashchange = function() { // Code that overwrites whatever was previously in window.onhashchange } 

虽然一个老问题, 地点栏项目是非常有用的。

 var LocationBar = require("location-bar"); var locationBar = new LocationBar(); // listen to all changes to the location bar locationBar.onChange(function (path) { console.log("the current url is", path); }); // listen to a specific change to location bar // eg Backbone builds on top of this method to implement // it's simple parametrized Backbone.Router locationBar.route(/some\-regex/, function () { // only called when the current url matches the regex }); locationBar.start({ pushState: true }); // update the address bar and add a new entry in browsers history locationBar.update("/some/url?param=123"); // update the address bar but don't add the entry in history locationBar.update("/some/url", {replace: true}); // update the address bar and call the `change` callback locationBar.update("/some/url", {trigger: true}); 

这个解决scheme为我工作:

 var oldURL = ""; var currentURL = window.location.href; function checkURLchange(currentURL){ if(currentURL != oldURL){ alert("url changed!"); oldURL = currentURL; } oldURL = window.location.href; setInterval(function() { checkURLchange(window.location.href); }, 1000); } checkURLchange(); 
 window.addEventListener("beforeunload", function (e) { // do something }, false); 

看看jQuery的卸载function。 它处理所有的事情。

https://api.jquery.com/unload/

当用户离开页面时,卸载事件被发送到窗口元素。 这可能意味着许多事情之一。 用户可以点击链接离开页面,或在地址栏中input新的URL。 前进和后退button将触发事件。 closures浏览器窗口将导致事件被触发。 即使页面重新加载也会首先创build一个卸载事件。

 $(window).unload( function(event) { alert("navigating"); } ); 

你在每次调用时都开始一个新的setInterval ,而不是取消前一个 – 可能你只是想有一个setTimeout