如何收听2019年window.location.search的更改

时间:2019-09-21 11:07:11

标签: javascript html query-string pushstate popstate

我想在不重新加载文档的情况下更新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));

这可行,但是我坚信必须有一种更优雅的方法。

1 个答案:

答案 0 :(得分:2)

最终答案:

我对下面的第二次尝试答案大为满意。

但是我真的不喜欢:

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点。


处理Point 2

MDN 报告:

  

请注意,只需调用history.pushState()history.replaceState()    不会触发弹出状态事件 。弹出状态事件 将被触发   通过执行浏览器操作(例如单击后退或前进)   按钮(或在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事件监听器进行工作,从而使我在逻辑上更加清晰,分离代码。


NB 我发现这很奇怪……仅按前进按钮 会触发window.popstate事件监听器,但调用{{1 }}不会...(需要紧接着添加window.history.pushState()来复制前进按钮的功能)。

但是,如上所述,这是我可以想到的最佳,最简洁,最优化的解决方案(就逻辑分离和将来的代码维护而言)。如果有人有更好的主意,我将很乐意转移这个绿色的勾号。


首先尝试回答:

我暂时得出结论,无法使用可以检测查询字符串何时更新的后台事件侦听器来实现此效果。

相反,由于我知道,可以确定查询字符串只需要检查

  • 页面加载或重新加载时
  • 调用history.back(); history.forward();

我可以使用以下内容:

window.history.pushstate

window.addEventListener('load', checkQueryString);