Question:
Hello. I stumbled upon changing the URL on Instagram, but the page does not reload. If you copy the URL to another window, but the infa is also loaded.
I suppose it happens like this: when I click on the link, I cancel the default action, I copy its href
to location.hash
, and I load the info with ajax'ом
, and if the user's browser does not support location.hash
, then I just don't cancel the default action on click on the link, and the person follows it.
Is this assumption valid? Or are there more concise options?
Answer:
<div class="link-group">
<a class="route" href="/orange">orange</a>
<a class="route" href="/tomato">tomato</a>
</div>
<script>
document.body.querySelectorAll('.route')
.forEach( link => link.addEventListener('click', link_clickHandler) );
function link_clickHandler( event ){
event.preventDefault();
let path = event.target.href;
window.history.pushState({route: path}, "some title", path);
}
window.addEventListener('popstate', window_popStateHandler);
function window_popStateHandler( event ){
if(event.state){
console.log(event.state)
}
console.log(event);
}
</script>
Here is the minimum code required to create a client router. Unfortunately, it will not work in the sandbox native to SO, and in the browser if loaded from the local file, probably too, but it works with the server.
What happens in the code –
- all links leading to a change in url are marked with the
route
class or in any other way. - when loading js, the first step is to select all the links and subscribe them to the
click
event. - in the
click
event handler, we callevent.preventDefault()
to prevent the default behavior of firing the link which will cause the page to reload. - using the History api , we put data about the current path and indicate the very url that we would like to see in the status bar. (one)
- we load the data using
ajax
and display it. - it is worth understanding that urls, although they look beautiful, like real ones, that is, without # shesh bars, in fact, they are not. If you go to the
http://localhost:8080
page and change the address tohttp://localhost:8080/orange
, then everything will work correctly. But going directly to the addresshttp://localhost:8080/orange
you will receive a404
error, since in reality such an address does not exist. For this, it is necessary that the server always returns theindex.html
page to absolutely any request. Then, by going to the addresshttp://localhost:8080/orange
, the browser is the code of the client router, which in turn recognizes the url and continues to work normally, collecting and loading data according to the specified rules. It is also worth understanding what exactly the client router should show the404
page, since only he knows which piti exist and which do not. - well, it’s worth adding that in an isomorphic application, almost everything is the same, except that when you enter the client part of the router, it works on the server and already rendered markup is placed in
index.html
.