I use history.pushState
and it works like a charm, except for the problem that once the url was manipulated correctly if you hit "back" in chromium or firefox, the url changes, but the page is not reloaded.
To elaborate:
We start at mysite.tld
Now (after some user interaction) we use history.pushState
and change the url to be mysite.tld/some/subpage
. The page gets re-rendered accordingly.
Now if you hit "back", the url changes, but NOT the page! If you refresh, the page is refreshed.
My naive (I am an absolute javascript noob) was to add an eventListener as such:
dom.window.addEventListener("popstate",
{
(event: Event) =>
{
dom.window.location.reload()
}
})
But of course that has some unpleasant sideeffects (whenever the url changes, it reloads the page. Very bad for eg galleries or slideshows)
The pushstate feature allows you to reflect the state of your client application in the browser history (URL, title).
This is the flow
popstate
event
state
property that is the data you've set when pushing state Look at this example (commented for explaination):
popstate.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>
Speaking of the gallery example, the identifier
could be the photo ID and render()
could update the source of the image. Of course you're responsible for fetching all or the next/previous photos (either via AJAX or inlined into the page source).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.