首页 > 解决方案 > 如何监听 2019 年 window.location.search 的变化

问题描述

我想在window.location.search 不重新加载文档的情况下进行更新,然后根据window.location.search.

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

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

到现在为止还挺好。浏览器 URL 栏中的window.location.search更新。

但我找不到检测此更新的一般后台事件侦听器 - 类似于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));

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

标签: javascripthtmlquery-stringpushstatepopstate

解决方案


最终答案:

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

但我真的不喜欢:

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

我采用popstate手动触发事件。

在实践中,我发现这种 hack 有时会奏效,有时会很慢,有时会完全失败。

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

经过反复搜索和试验(这非常难找到),我终于找到了手动触发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()orhistory.replaceState() 不会触发 popstate 事件。popstate 事件 通过执行浏览器操作来触发,例如单击后退或前进按钮(或调用history.back()history.forward()在 JavaScript 中)。

来源: 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();

推荐阅读