如何将history.pushState与浏览器的后退功能结合使用



我使用history.pushState,它就像一个魅力,除了一旦网址被正确操作的问题,如果你在 chromium 或 Firefox 中点击"后退",网址会改变,但页面不会重新加载。

详细阐述:

我们从mysite.tld开始

现在(经过一些用户交互(我们使用history.pushState并将 url 更改为mysite.tld/some/subpage.页面将相应地重新呈现。

现在,如果您点击"返回",网址会更改,但页面不会更改! 如果刷新,页面将刷新。

我的天真(我是一个绝对的javascript菜鸟(是添加一个eventListener:

dom.window.addEventListener("popstate",
{
(event: Event) =>
{
dom.window.location.reload()
}
})

但是当然,这有一些令人不快的副作用(每当URL更改时,它都会重新加载页面。对于例如画廊或幻灯片非常糟糕(

pushstate 功能允许您在浏览器历史记录(URL、标题(中反映客户端应用程序的状态。

这是流程

  • 用户更改应用程序的状态
  • 应用程序更改历史记录的状态
    • 设置表示应用程序状态的数据(例如显示的当前数据(
    • 设置 URL 以反映应用程序的状态
  • 用户导航(更改状态(,这会触发popstate事件
    • 该事件包含一个state属性,该属性是推送状态时设置的数据
    • 根据状态更新应用程序的视图

看看这个例子(注释说明(:

流行状态.html

<!DOCTYPE html>
<html>
<head>
<title>Pushstate/Popstate</title>
</head>
<body>
<a href="javascript: void(0)">increment</a>
<div id="output">?</div>
<script type="text/javascript">
window.onload = function() {
let identifier = 0,
match,
query,
identifiererEl = document.getElementById("output");
// - Since all URL properties can be accessed clientside, 
//   the request data is extracted from the current URL.
// - This can be seen like an ID that the server may use 
//   to find the actual content
// - Note that history.state makes no sense in this case, 
//   since it is null when the script first runs.
match = /identifier=(d+)/.exec(location.search);
// This emulates the behaviour of a server it won't make sense in 
// a client side application
if (match) {
// Set the identifier with the data "from the server"
identifier = Number(match[1]) || 0;
// Make the view initially reflect the state
render(identifier);
}
function render(text) {
identifiererEl.textContent = text;
}
// Listen to user interaction to alter the data, render and 
// push the state
document.querySelector("a").addEventListener("click", (e) => {
// Increment only for simplicity
identifier++;
render(identifier);
history.pushState(
{ identifier: identifier },
"",
`/popstate.html?identifier=${identifier}`
);
});
// Listen to state changes to update the view
window.addEventListener("popstate", (e) => {
// Here you'd determine the actual data to render.
// For simplicity the identifier itself is rendered.
render(e.state.identifier);
});
};
</script>
</body>
</html>

说到图库示例,identifier可以是照片 ID,render()可以更新图像的来源。当然,您负责获取所有或下一张/上一张照片(通过AJAX或内联到页面源代码中(。

最新更新