如何检测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
事件(及其onpopstate
callback函数)。 因此,原始答案并不适用于所有情况。
但有一种方法可以通过按照@ 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