Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add or append new stateObject to history

Tags:

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.

like image 682
choz Avatar asked Apr 29 '16 03:04

choz


1 Answers

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

You may push 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 have to explicitly 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 use the same state object and modify it (even if according to the standard, history.state is supposed to be a clone of the actual state data). You should create a new object instead (it may be a clone of the previous state).

Here is how you can do it.

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

It will work even if there is no current state in the history (i.e. window.history.state is undefined) as Object.assign ignores undefined arguments.

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 also copy the properties of the previous state in the new state. So instead of the previous code you can do:

extendHistoryState({scrollTop: scrollTop}, "RandomTitle", '#');
like image 87
Quentin Roy Avatar answered Sep 28 '22 03:09

Quentin Roy