如何在2019年监听对window.location.search的更改



我想在不重新加载文档的情况下更新window.location.search,然后根据window.location.search中更新的值执行函数。

当用户单击某个按钮时,该按钮的onclick事件将触发以下函数:

window.history.pushState({action : 'myAction'}, document.title, '?action=myAction');

目前为止,一切都好。window.location.search会在浏览器 URL 栏中更新。

但是我找不到检测到此更新的常规后台事件侦听器 - 类似于onhashchange但用于查询字符串。

我能想到的最好的是:

window.history.pushState({action : 'myAction'}, document.title, '?action=myAction');
window.history.pushState({action : 'myAction'}, document.title, '?action=myAction');
window.history.back();
window.addEventListener('popstate', () => console.log(event.state.action));

这行得通,但我相信必须有一种更优雅的方法。

最终答案:

我对下面的第二次尝试答案非常满意。

但我真的不喜欢:

history.back();
history.forward();

我采用它来手动触发popstate事件。

在实践中,我发现这个黑客有时有效,有时很慢,有时完全失败。

在纸面上,感觉太临时了。

经过反复搜索和试验(这很难找到(,我终于找到了手动触发popstate事件的正确语法。

就像dispatching这样简单

new Event('popstate')

喜欢这个:

let myEvent = new Event('popstate');
window.dispatchEvent(myEvent);

所以最终的代码是:

window.history.pushState({action : 'myAction'}, document.title, '?action=myAction');
let queryStringChange = new Event('popstate');
window.dispatchEvent(queryStringChange);

我能想出的最佳答案(第二次尝试(:

基于以下内容:

我确信查询字符串只需要检查

  1. 当页面加载或重新加载时;

  2. 调用window.history.pushstate时;

  3. 或者当(正如@Kaiido下面的评论中敏锐地指出的那样(通过前进和后退按钮访问页面时

我也知道:

  • window.load事件侦听器涵盖第 1 点;
  • window.popstate事件侦听器涵盖第 3 点。

这只剩下第 2 点。


处理第 2 点

正如MDN报道的那样:

请注意,只需调用history.pushState()history.replaceState()不会触发流行状态事件。popstate 事件将通过执行浏览器操作(例如单击后退或前进(来触发按钮(或在 JavaScript 中调用history.back()history.forward()(。

来源:https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event

但这意味着而不是使用(如我第一次尝试,如下(:

window.history.pushState({action : 'myAction'}, document.title, '?action=myAction');
checkQueryString(); // DIRECT INVOCATION OF FUNCTION

我可以改用:

window.history.pushState({action : 'myAction'}, document.title, '?action=myAction');
history.back();
history.forward();

这意味着我现在可以允许覆盖第 3 点的同一window.popstate事件侦听器完成其工作,从而为我提供更干净、逻辑上更分离的代码,而不是直接调用函数。

<小时 />

注意我发现...奇怪。。。仅按转发按钮触发window.popstate事件侦听器,但调用window.history.pushState()不会...(需要紧随其后的添加history.back(); history.forward();以复制前进按钮的功能(。

但是,如上所述,这是我能想到的最好、最干净、最优化(就逻辑分离和未来代码维护而言(的解决方案。如果有人有更好的主意,我很乐意转移绿色勾号。


第一次尝试回答:

我初步得出结论,没有办法使用后台事件侦听器来实现这种效果,该侦听器可以检测查询字符串何时更新。

相反,因为我确定查询字符串只需要检查

  • 当页面加载或重新加载时
  • 调用window.history.pushstate

我可以使用以下内容:

window.addEventListener('load', checkQueryString);

window.history.pushState({action : 'myAction'}, document.title, '?action=myAction');
checkQueryString();

最新更新