如何将新的stateObject添加或追加到历史记录中

vad*_*lim 5 javascript

我有以下代码来保存我data当前的页面状态.

window.history.pushState({myData: data}, "RandomTitle", '#');
Run Code Online (Sandbox Code Playgroud)

但现在,我想保存另一个值scrollTop.如果我这样做

window.history.pushState({scrollTop: scrollTop}, "RandomTitle", '#');
Run Code Online (Sandbox Code Playgroud)

上面的代码将用新的代码替换历史状态,并且myData将消失.

现在的问题是有反正我可以补充scrollTop,同时有myData在我的历史状态?或者我只需要将它设置为最初,

window.history.pushState({myData: data, scrollTop: 0}, "RandomTitle", '#');
// To change the scrollTop in history state
window.history.state.scrollTop = $(window).scrollTop();
Run Code Online (Sandbox Code Playgroud)

我在想是否有类似的功能window.history.state.addObject.

Que*_*Roy 4

默认情况下,没有任何history.state.addObject功能。 history.state包含您推送的对象(没有其他内容)。

你可能会推送一些有addObject方法的东西,但这看起来不是一个好主意。如果您希望将更改作为新状态推送到历史记录中,则无论如何每次都必须显式推送该状态。当你推送一个新状态时,你希望避免改变前一个状态,如果你使用相同的状态对象并修改它,就会发生这种情况(即使根据标准history.state应该是实际状态数据的克隆) 。您应该创建一个新对象(它可能是先前状态的克隆)。

以下是您可以如何做到这一点。

window.history.pushState(
  Object.assign({}, window.history.state, {scrollTop: scrollTop}),
  "RandomTitle", '#'
);
Run Code Online (Sandbox Code Playgroud)

即使历史记录中没有当前状态(即window.history.stateis undefined),它也会工作,因为Object.assign忽略undefined参数。

您还可以使用此函数来自动执行此操作:

function extendHistoryState(){
   arguments[0] = Object.assign({}, window.history.state, arguments[0]);
   window.history.pushState.apply(window.history, arguments);
}
Run Code Online (Sandbox Code Playgroud)

它的工作原理与(相同的参数)完全相同pushState,只是它还会将先前状态的属性复制到新状态中。因此,您可以执行以下操作来代替之前的代码:

extendHistoryState({scrollTop: scrollTop}, "RandomTitle", '#');
Run Code Online (Sandbox Code Playgroud)