69

我已经读了十几遍了,状态对象可能存在多个键|值对,并且它与新的历史条目相关联。但是有人可以给我一个状态对象的好处的例子吗?它的实际用途是什么?我无法想象为什么不直接输入 {}

4

3 回答 3

112

以这个小例子 -运行小提琴

您有一个用户可以选择颜色的页面。每次他们这样做时,我们都会生成一个新的历史条目:

function doPushState (color) {
    var state = {},
        title = "Page title",
        path  = "/" + color;
    
    history.pushState(state, title, path);
};

我们暂时将状态对象留空,并将 URL 设置为颜色名称(不要重新加载页面 - 该 URL 不存在,因此您将得到 404)。

现在单击红色、绿色和蓝色各一次。请注意,URL 会发生变化。现在,如果您单击后退按钮会发生什么?

浏览器确实回到了历史,但我们的页面没有注意到 - URL 从“/蓝色”变回“/绿色”,但我们的页面停留在“您选择了蓝色”。我们的页面与 URL 不同步。

这就是window.onpopstate事件和状态对象的用途:

  1. 我们在状态对象中包含我们选择的颜色
function doPushState (color) {
    var state = { selectedColor: color }, // <--- here
        title = "Page title",
        path  = "/" + color;
    
    history.pushState(state, title, path);
};
  1. 然后我们监听这个popstate事件,这样我们就知道什么时候必须更新选择的颜色,就是这样:
window.addEventListener('popstate', function (event) {
    var state = event.state;
    
    if (state) {
        selectColor( state.selectedColor );
    }
});

试试更新后的例子:run fiddle:当用户浏览历史记录时,我们的页面现在会相应更新。

于 2013-12-12T13:16:42.807 回答
1

是一个特定且具有前瞻性的用例,使用在视图中按区域划分的自定义元素和模板在渐进式应用程序中维护用户视图和数据状态

想象一个 64 格的网格作为您的视图,在大屏幕上,每个格子是 147 ^2

url代表64/个用户ID abs相关用户数据

然后,Web 应用程序可以用用户特定的状态数据填充其网格

在这个用例中,我完全相信未来,用户不想分享他或她的个人状态和数据填充视图部分

通过使用以前的历史状态及其相关的 650k 数据

可以使用一些众所周知的排序方法从浏览器历史记录和位置(包括状态)重新组装一个完整的复杂应用程序。

这个很酷

于 2016-09-14T06:12:44.000 回答
0

如果您不想,它可以让您选择不将所有数据存储在 URL 中。

打开您的控制台并尝试以下操作:

首先做一个监听器

window.addEventListener('popstate', function (event) {    
    console.log(`You first visited this page at ${event.state.time}`)
});

然后在控制台中推送一个状态几次,每次之间稍等片刻以获得不同的时间(不要复制和粘贴整个块。复制第一行并提交到控制台几次):

history.pushState({time:new Date().getTime()},'','/foo');
history.pushState({time:new Date().getTime()},'','/foo');
history.pushState({time:new Date().getTime()},'','/foo');
history.pushState({time:new Date().getTime()},'','/foo');
history.pushState({time:new Date().getTime()},'','/foo');
history.pushState({time:new Date().getTime()},'','/foo');

现在在浏览器中按下后退按钮并查看控制台。

对于现实世界中的大多数用例来说,状态对象可能并不理想——通常您希望 URL 完整地描述您将要看到的内容。

于 2021-12-26T22:04:21.433 回答