choz choz - 7 months ago 27
Javascript Question

How to add or append new stateObject to history

I have the following code to save my

data
in current page state.

window.history.pushState({myData: data}, "RandomTitle", '#');


But now, I want to also save another value which is
scrollTop
. And if I do

window.history.pushState({scrollTop: scrollTop}, "RandomTitle", '#');


The code above will replace the history state with the new one and
myData
will be gone.

The question, Is there anyway I can add
scrollTop
while there's
myData
in my history state? Or I just have to set it initially like,

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


I am thinking if there's a function like
window.history.state.addObject
or something.

Answer

By default, there is no history.state.addObject function. history.state contains the object that you pushed (and nothing else).

You may push an something that has an addObject method, but it does not look like a good idea. If you want the change to be pushed in the history as a new state, you need to re-push the state each time anyway. And when you push a new state, you want to avoid mutating the previous one – which will happen if you fetch the state object and modify it – or you are going to make a mess of your history. You should create a new object instead (that may be a copy of the previous state).

Here is how you can do it.

window.history.pushState(
  Object.assign({}, window.history.state, {scrollTop: scrollTop}),
  "RandomTitle", '#'
);

You can also use this function that automates it:

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

It works exactly like pushState (same arguments) except that it will keep the previous state's properties (except if they are in the provided new state). So instead of the previous code you can do:

extendHistoryState({scrollTop: scrollTop}, "RandomTitle", '#');