Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect URL changes in SPA

Tags:

Note

Solution should be in pure Javascript - No external library and frameworks.


In SPA, Everything gets routed using routing mechanism. I just want to listen to an even whenever any part of url changes (Not only hash. Any change I want to detect)

Following is example of SPA,

https://www.google.in/
https://www.google.in/women 
https://www.google.in/girl 

Now whenever url changes from https://www.hopscotch.in/ to https://www.hopscotch.in/women, I want to capture that event.

I tried,

window.addEventListener("hashchange",function(event){
    console.log(this); // this gets fired only when hash changes
});
like image 688
Deepak Ingole Avatar asked Jun 07 '16 10:06

Deepak Ingole


2 Answers

In addition to Quentin's answer: setInterval is a pretty bad way to check for these changes: it's either never on time or gets fired too often.

What you really should do is watch for user-input events. Click is the most obvious one but don't forget about keyboard input. Should one of these events occur it will mostly just take one tick for the url to change. So in a quick mockup in code it's:

let url = location.href;
document.body.addEventListener('click', ()=>{
    requestAnimationFrame(()=>{
      url!==location.href&&console.log('url changed');
      url = location.href;
    });
}, true);

(just drop it into Github console to see it work)

Together with a popstate listener this should be enough for most use cases.

like image 114
Sjeiti Avatar answered Sep 17 '22 15:09

Sjeiti


Under normal circumstances, there isn't an event when the URL changes. You are loading a new document (although you have load and so on)

If you are setting a new URL with JavaScript (i.e. with pushState) then there isn't an event, but you don't need one because you're already explicitly writing code around it, so you just add whatever else you need to that code.

You'll get a popstate event if the URL changes back though your pushState history via the browser back button or similar.


Consequently, there is no good generic way to hook into every SPA. The closest you could come would be to use setInterval and inspect the value of location.href to see if it changed since the last inspection.

like image 41
Quentin Avatar answered Sep 20 '22 15:09

Quentin