当URL参数改变时的监听器事件

14

我有一个带分页和筛选器的单页面应用程序,需要检测当前URL是否发生了任何变化。是否有一种简单的方法可以添加监听器到当前URL,并在其更改时触发某些操作?(也不要使用设置间隔!)

  1. 用户打开 www.foobar.com
  2. 用户进行某些操作,URL更改为 www.foobar.com?filter=hello
  3. 我的函数运行

我已经尝试过 onhashchange 和 unbeforeunload,但都不适用于此情况。

window.onbeforeunload = function(e) {
   alert ('url changed!');
};

window.onhashchange = function() { 
alert ('url changed!');  
}

是否有一种方法可以在URL更改时添加监听器,并在任何更改时触发某些操作?(再次强调,这是单页面应用程序,因此不会刷新)


1
可能是如何在JavaScript中检测URL更改的重复问题。 - klugjo
我看了一下,那是一个“onhashchange”的情况。我的有点不同,没有哈希,而且我不想设置间隔时间。 - user3390251
@klugjo 不是 - 因为它在 URL 中有一个 has。这里只是简单的参数。 - Beni Sinca
2个回答

10
如果您不想使用setInterval,您可以覆盖history.pushState事件:
(function(history){
    const pushState = history.pushState;
    history.pushState = function(state) {
        if (typeof history.onpushstate == "function") {
            history.onpushstate({state: state});
        }
        // Call your custom function here
        return pushState.apply(history, arguments);
    }
})(window.history);

这已经接近成功了!尽管它给我控制台错误信息:未捕获的类型错误:无法在“历史记录”上执行'pushState':需要2个参数,但只提供了1个。这可能与站点上的其他代码冲突... - user3390251
为什么要用History,不应该是小写的history吗? - klugjo
2
箭头函数不会暴露出 arguments 对象,你需要使用 history.pushState = (state, ...args) => {pushState.call(history, state, ...args); - user4639281

8
你可以使用MutationObserver来监听URL变化等事件:
let previousUrl = '';
const observer = new MutationObserver(function(mutations) {
  if (window.location.href !== previousUrl) {
      previousUrl = window.location.href;
      console.log(`URL changed from ${previousUrl} to ${window.location.href}`);
    }
});
const config = {subtree: true, childList: true};

// start listening to changes
observer.observe(document, config);

// stop listening to changes
// observer.disconnect();

1
通过像这样使用MutationObserver,你并不是在监听URL的变化,而是监听DOM的变化,并尝试捕获URL变化作为可能的副作用。但URL完全有可能在没有任何DOM改变的情况下发生变化。 - ArcadeRenegade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接