我正在处理单页应用,我遇到了HTML5历史API的问题,或者说这种行为非常令人期待,我只是不知道如何解决它
我们没有使用任何框架,所以请记住,仅限原生。
TL; DR:如果历史状态仅更改window.onpopstate
而不是#hash
,因为所有内容都已存在,如何阻止location.url
处理程序触发,只是哈希从#something
更改为无哈希(初始页面加载)
让我们说我们在这个应用程序的主页上。我们导航到某个页面,让我们说 Page 1 (此页面通过AJAX加载并几乎取代整个主页)以及使用history.pushState()
进行输入以便我们可以导航回来。现在在第1页,我们有一些像这样的锚:
<a href="#content1">
<a href="#content2">
这些显然指向Page1的某些部分,这些部分是带有提到的ID的div。然而,他们也做了一个历史条目。所以,让我们说我们的导航路线是这样的:
主页&gt;第1页&gt; #content1&gt; #内容2。
现在当我们点击后退按钮时,它来自#content2&gt; #content1,这很好,因为window.onpopstate
处理程序(见下文)旨在激发它适当的AJAX调用,以防我们使用特定的状态对象进行history.pushState
调用。但是,当用户再次点击后退按钮时:
#content1&gt;第1页
这就是出现问题的地方。
也就是说,单击Page1时创建的history.pushState()
确实具有触发AJAX调用所需的状态对象。即使所有内容都已存在且我们所做的一切都在浏览页面的锚点,也会重新加载内容。
我该如何阻止这种情况?
我试过看location.hash
是否有window.onpopstate
事件中先前状态的信息,但是一旦此事件触发,该位置已经更新,因此我无法检查位置是否仍然存在相同并拦截AJAX调用。
如何区分#hash历史状态和正确的状态切换?
windows.onpopstate处理程序:
//state.ExeSce makes sure that this was indeed a history.pushState that we want
if (event.state && event.state["ExeSce"]) {
var params = new Map(window.location.search.substring(1).split("&").map(function (element) {
return element.split("=");
}));
var tempObj = {};
var process = event.state['process'];
var activity = event.state['activity'];;
params.forEach(function (value, key) {
tempObj[key] = value;
});
ExecuteScenario('POST', process, activity, tempObj);
//This fires the AJAX call function with all the necessary data.
}
编辑另外,关于在网址中使用#hash进行备份的主题,为什么浏览器在#hash id&#39; s时无法滚动到div?我们回顾/前进历史?我不得不在popstate上手动元素.scrollIntoView()。