如何检测在 JavaScript 中的哈希值后 URL 是否已更改

2022-08-30 00:57:09

如何检查 JavaScript 中的 URL 是否已更改?例如,像 GitHub 这样使用 AJAX 的网站会在 # 符号后附加页面信息,以创建唯一的 URL,而无需重新加载页面。检测此 URL 是否更改的最佳方法是什么?

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

答案 1

我希望能够添加事件侦听器。经过下面的修改后,我们将能够做到这一点,就像这样locationchange

window.addEventListener('locationchange', function () {
    console.log('location changed!');
});

相比之下,仅当URL中主题标签之后的部分发生变化时才会触发,并且并不总是有效。window.addEventListener('hashchange',() => {})window.addEventListener('popstate',() => {})

这种修改与克里斯蒂安的答案类似,修改了历史对象以添加一些功能。

默认情况下,在这些修改之前,存在一个事件,但没有 、 和 的事件。popstatepushstatereplacestate

这将修改这三个函数,以便所有函数都触发一个自定义事件供您使用,并且如果您要使用这些函数,还可以触发事件。locationchangepushstatereplacestate

这些是修改:

(() => {
    let oldPushState = history.pushState;
    history.pushState = function pushState() {
        let ret = oldPushState.apply(this, arguments);
        window.dispatchEvent(new Event('pushstate'));
        window.dispatchEvent(new Event('locationchange'));
        return ret;
    };

    let oldReplaceState = history.replaceState;
    history.replaceState = function replaceState() {
        let ret = oldReplaceState.apply(this, arguments);
        window.dispatchEvent(new Event('replacestate'));
        window.dispatchEvent(new Event('locationchange'));
        return ret;
    };

    window.addEventListener('popstate', () => {
        window.dispatchEvent(new Event('locationchange'));
    });
})();

请注意,我们正在创建一个闭包,以将旧函数保存为新函数的一部分,以便在调用新函数时调用它。


答案 2

在现代浏览器(IE8+、FF3.6+、Chrome)中,您只需收听 .hashchangewindow

在某些旧浏览器中,您需要一个不断检查的计时器。如果您使用的是jQuery,那么有一个插件可以做到这一点。location.hash

下面我撤消任何URL更改,以保持滚动:

<script type="text/javascript">
  if (window.history) {
    var myOldUrl = window.location.href;
    window.addEventListener('hashchange', function(){
      window.history.pushState({}, null, myOldUrl);
    });
  }
</script>

请注意,上面使用的-API在Chrome,Safari,Firefox 4 +和Internet Explorer 10pp4 +中可用history