在 js 中处理 URL 锚点更改事件

IT技术 javascript event-handling dom-events fragment-identifier hashchange
2021-01-26 18:10:00

如何编写将在 URL 锚点发生任何更改时执行的 JavaScript 回调代码?

例如从http://example.com#ahttp://example.com#b

6个回答

Google 自定义搜索引擎使用计时器根据先前值检查哈希值,而单独域上的子 iframe 更新父级的位置哈希值以包含 iframe 文档正文的大小。当计时器捕捉到变化时,父级可以调整 iframe 的大小以匹配正文的大小,以便不显示滚动条。

像下面这样的东西也能达到同样的效果:

var storedHash = window.location.hash;
window.setInterval(function () {
    if (window.location.hash != storedHash) {
        storedHash = window.location.hash;
        hashChanged(storedHash);
    }
}, 100); // Google uses 100ms intervals I think, might be lower

Google Chrome 5、Safari 5、Opera 10.60Firefox 3.6Internet Explorer 8 支持该hashchange事件:

if ("onhashchange" in window) // does the browser support the hashchange event?
    window.onhashchange = function () {
        hashChanged(window.location.hash);
    }

并将其放在一起:

if ("onhashchange" in window) { // event supported?
    window.onhashchange = function () {
        hashChanged(window.location.hash);
    }
}
else { // event not supported:
    var storedHash = window.location.hash;
    window.setInterval(function () {
        if (window.location.hash != storedHash) {
            storedHash = window.location.hash;
            hashChanged(storedHash);
        }
    }, 100);
}

jQuery 还有一个插件可以检查 hashchange 事件并在必要时提供它自己的 - http://benalman.com/projects/jquery-hashchange-plugin/

编辑:更新浏览器支持(再次)。

现在你可以hashChangestackoverflow.com/questions/6390341/how-to-detect-url-change收听window
2021-03-18 18:10:00
为完整起见,请添加var storedHash = window.location.hash;到汇总摘要块中。顺便说一句:现在我认为这被称为 polyfill。
2021-03-30 18:10:00
@AndyE 我确实阅读了答案,我错过了小纸条,而且我从未见过类似的事件 hashChanged(storedHash);
2021-04-03 18:10:00
我正在寻找一些轻量级的 JS 路由器,但这很好地完成了这项工作。还消除了所有依赖项:)
2021-04-05 18:10:00
@TimoHuovinen:hashChanged在这种情况下,旨在成为开发人员使用此代码实现的功能。这里的答案只是演示了如何在onhashchange事件不可用的情况监视哈希值的更改,并结合基于事件和基于计时器的方法来提供通用解决方案。我的观点是,您链接到的答案对此处的答案绝对没有任何补充;-)。它们提供相同的基本信息,甚至是 Ben Alman 的 jQuery 插件的链接。唯一的区别是我在回答中提供了纯 JS 解决方案。
2021-04-10 18:10:00

我建议使用addEventListener而不是覆盖window.onhashchange,否则您将阻止其他插件的事件。

window.addEventListener('hashchange', function() {
...
})

看看当今全球浏览器的使用情况,不再需要回退。

从我在其他 SO 问题中看到的,唯一可行的跨浏览器解决方案是计时器。例如,看看这个问题

setInterval()目前只是通用解决方案。但未来有一些亮点以hashchange 事件的形式出现

仅供参考:Mozilla 开发者网络上的onhashchange活动文档
2021-03-18 18:10:00

(仅供记录。)YUI3“hashchange”合成事件或多或少与接受的答案相同

YUI().use('history-hash', function (Y) {
  Y.on('hashchange', function (e) {
    // Handle hashchange events on the current window.
  }, Y.config.win);
});