如何检查URL是否在JavaScript中发生了变化?例如,像GitHub这样使用AJAX的网站,会在#符号后附加页面信息,以创建唯一的URL,而无需重新加载页面。检测该URL是否发生变化的最佳方法是什么?
是否再次调用onload事件? 是否有URL的事件处理程序? 或者必须每秒钟检查URL以检测更改?
如何检查URL是否在JavaScript中发生了变化?例如,像GitHub这样使用AJAX的网站,会在#符号后附加页面信息,以创建唯一的URL,而无需重新加载页面。检测该URL是否发生变化的最佳方法是什么?
是否再次调用onload事件? 是否有URL的事件处理程序? 或者必须每秒钟检查URL以检测更改?
当前回答
虽然这是一个老问题,但位置栏项目非常有用。
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
// e.g. 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});
其他回答
适用于Chrome 102+ (2022-05-24)
navigation.addEventListener("navigate", e => {
console.log(`navigate ->`,e.destination.url)
});
消防引用巫术崇拜者
在一个单独的线程中找到了一个工作答案:
没有一个事件是永远有效的,对于大多数大型spa来说,monkey patch pushState事件是非常偶然的。
所以聪明的投票对我来说是最有效的。您可以添加任意多的事件类型,但这些似乎对我来说做得很好。
为TS编写,但很容易修改:
const locationChangeEventType = "MY_APP-location-change";
// called on creation and every url change
export function observeUrlChanges(cb: (loc: Location) => any) {
assertLocationChangeObserver();
window.addEventListener(locationChangeEventType, () => cb(window.location));
cb(window.location);
}
function assertLocationChangeObserver() {
const state = window as any as { MY_APP_locationWatchSetup: any };
if (state.MY_APP_locationWatchSetup) { return; }
state.MY_APP_locationWatchSetup = true;
let lastHref = location.href;
["popstate", "click", "keydown", "keyup", "touchstart", "touchend"].forEach((eventType) => {
window.addEventListener(eventType, () => {
requestAnimationFrame(() => {
const currentHref = location.href;
if (currentHref !== lastHref) {
lastHref = currentHref;
window.dispatchEvent(new Event(locationChangeEventType));
}
})
})
});
}
使用
observeUrlChanges((loc) => {
console.log(loc.href)
})
当点击链接将你重定向到同一域名的不同页面时,这些似乎都不起作用。因此,我提出了自己的解决方案:
let pathname = location.pathname;
window.addEventListener("click", function() {
if (location.pathname != pathname) {
pathname = location.pathname;
// code
}
});
编辑:您还可以检查popstate事件(如果用户返回一个页面)
window.addEventListener("popstate", function() {
// code
});
最好的祝愿,
微积分
用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
}
window.onpopstate = function() {
//code
}
or
window.addEventListener('hashchange', function() {
//code
});
window.addEventListener('popstate', function() {
//code
});
与jQuery
$(window).bind('hashchange', function() {
//code
});
$(window).bind('popstate', function() {
//code
});