HTML5:当popstate被触发时刷新页面

14

我有一个像这样的ajax搜索表单:

网址: /search/

=>用户输入搜索词并点击按钮

=> 搜索完成后,通过ajax在页面上的一个div中显示结果

但是: 我也希望用户能够复制&paste URL 给好友,并浏览之前的搜索结果。所以当触发搜索时,我会从浏览器地址栏中将URL更改为:

/search/?q=yourkeyword

使用以下方法:

window.history.pushState("", "Search for "+keyword, "/search/?q="+keyword);

这将在浏览器地址栏中更改url为/search/?q=yourkeywords,并且运行良好。

现在,点击后退按钮,浏览器地址栏会再次显示/search/,这很好。 但是页面内容没有重新加载,它仍然显示来自/search/?q=yourkeyword的结果。

所以我添加了:

window.addEventListener("popstate", function(e) 
{   location.reload();
});

这是正确的方法吗?在桌面浏览器(如FF和Chrome)中运行良好,但例如在iOS中,popstate事件在/search/上第一次加载searchform时被触发,导致页面不断刷新。

什么是正确的做法?

3个回答

11

最简单的解决方案是在使用pushState时设置一个全局变量。然后,在您的onpopstate处理程序中,只需检查是否已设置该变量即可。例如:

window.historyInitiated = true;
window.history.pushState("", "Search for "+keyword, "/search/?q="+keyword);
...
window.addEventListener("popstate", function(e) {
  if (window.historyInitiated) {
    window.location.reload();
  }
});

1
我认为这应该是被接受的答案。对于我们(相同的)使用情况完美地工作。 - NickGreen

2

2022年的新闻

当所有主要浏览器在页面加载时开始不发出popstate事件时,此问题得到解决。因此,现在简单地执行以下操作应该是相对安全的:

window.addEventListener("popstate", function(e){
  location.reload();
});

现在所有的主流浏览器都会在用户通过“前进”和“后退”按钮导航到一个由pushState()添加的历史记录条目时始终触发popstate事件,但是当网页通过刷新按钮加载时,永远不会触发popstate事件。

以下是来自https://developer.mozilla.org/en-US/docs/Web/API/PopStateEvent的引用:

注意:浏览器以前在页面加载时对popstate事件的处理方式不同,但现在它们的行为相同。Firefox从未在页面加载时发出popstate事件。Chrome在版本34之前一直发出popstate事件,而Safari在版本10.0之前一直发出popstate事件。


1
我的建议:
window.location.href = window.location.href;

我没有测试过它,但我认为它将会实现你想要的功能。

感谢您的回复。我认为location.reload()和您的解决方案是相同的。但问题在于,即使只是加载页面,iOS也会触发popstate事件,因此仅浏览/search/(在之前没有进行任何pushState操作)就会触发popstate事件。 - Werner
我猜你得测试不同的情况。我想我接下来要做的是创建一个变量,在页面加载完成后设置该变量。只有在该变量被设置时才进行重新加载。 - Dan Goodspeed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接