JavaScript event listener for URL changes



  • Here in the modern world, SPAs frequently change their URLs. For example, this site does it every few seconds while you're scrolling down a thread.

    I'm trying to find a reliable event listener so my script is notified every time the URL changes. So far I've found:

    This seems to only trigger when you run history.back() or history.go().

    The description at the top says:

    Note that just calling history.pushState() or history.replaceState() won't trigger a popstate event. The popstate event will be triggered by doing a browser action such as a click on the back or forward button (or calling history.back() or history.forward() in JavaScript).

    This seems to trigger only if the page scrolls to an anchor tag.

    history.pushState() also has this little gem in its description:

    Note that pushState() never causes a hashchange event to be fired, even if the new URL differs from the old URL only in its hash.

    ... it really feels like popstate should do what I need, am I misreading the documentation or what's going on here?

    EDIT: I should specify I have no control over the source for the page. My script is simply added to the page after-the-fact, so I can't do any solution that involves, for example, manually sending a popstate event after running history.pushState(). Which seems to be what a StackOverflow thread I found recommends.



  • @blakeyrat

    you got events like:

    I dunno how that would work with an SPA.

    Might be worth sticking it in and seeing if it gets fired on a browser history change event.



  • @lucas1 said in JavaScript event listener for URL changes:

    Might be worth sticking it in and seeing if it gets fired on a browser history change event.

    It doesn't.

    It's boggling my mind that at some point the DOM guys added in the complete ability to change current URL and history, but seem to have neglected to include any event that gets fired when it actually happens... I have to be missing something, right?



  • @blakeyrat Interesting.

    The guys that were programming it were thinking of people that weren't trying to add stuff like tracking scripts (or whatever you are doing). They were thinking about application developers.

    I can't be arsed today but I might write some test cases of when this works at the weekend. I also want to know this as this doesn't work as I expected.



  • You can replace pushState with your own function, like so:

    var realPushState = history.pushState;
    history.pushState = function(some, args, I, dunno) {
        // do the thing you want to do
    
        return realPushState.apply(history, arguments); // leave this line exactly as-is.
    };
    


  • @ben_lubar It is a bit filthy but that should work. Nice one.



  • @ben_lubar Seems dangerous. Believe me, I know monkeypatching, I'd done legions of it in the past.

    Better would be just to check that the URL hasn't changed every time I need to track some data.

    The fact that his problem exists is ridiculous, though. The web is awful. Why are web developers ok with this?



  • Because the web is a ton of hacks. Make your money with it and be happy man. FFS.


  • Considered Harmful

    @blakeyrat said in JavaScript event listener for URL changes:

    @ben_lubar Seems dangerous. Believe me, I know monkeypatching, I'd done legions of it in the past.

    Better would be just to check that the URL hasn't changed every time I need to track some data.

    The fact that his problem exists is ridiculous, though. The web is awful. Why are web developers ok with this?

    The webdevs see no point in complaining and ECMA sees no one who complains.



  • @pie_flavor said in JavaScript event listener for URL changes:

    The webdevs see no point in complaining and ECMA sees no one who complains.

    Well this is all DOM anyway. So it's W3C doing a terrible job, not ECMA doing a terrible job. Either way it's a terrible job.

    Still open to suggestions that don't involve just periodically checking that location.protocol + '//' + location.host + location.pathname; hasn't changed from the previous value.



  • @blakeyrat It is neither.

    You and @pie_flavor seem to think every API must be cast in stone forever.

    The fact is that I can probably shim a .NET 4.6 application to work on a .NET 4.0 runtime, with some wankery.

    If you know how you are abusing the platform and you abuse it in a way that is for your site only and is in a responsible way .. then that is part of being a developer e.g. being smart enough to bend the tech to your will.

    I have spent too much time with developers which would either completely abuse language features or slavishly adhere to the standards.



  • This post is deleted!


  • @blakeyrat said in JavaScript event listener for URL changes:

    Considering .NET 4.6 already uses the 4.0 runtime, that's pretty easy to accomplish.

    HAHAHAHAHA.

    That shows how much you know straight away.



  • @blakeyrat said in JavaScript event listener for URL changes:

    Yes yes and this program does abuse the tech in a responsible way elsewhere. That doesn't mean I'd prefer to do that if it's at all avoidable. That also doesn't mean I can't criticize DOM for having extremely obvious feature gaps in it.

    It doesn't. It has an extensible API for people who aren't rigid as yourself in their thinking.


  • Considered Harmful

    @lucas1 said in JavaScript event listener for URL changes:

    @blakeyrat said in JavaScript event listener for URL changes:

    Yes yes and this program does abuse the tech in a responsible way elsewhere. That doesn't mean I'd prefer to do that if it's at all avoidable. That also doesn't mean I can't criticize DOM for having extremely obvious feature gaps in it.

    It doesn't. It has an extensible API for people who aren't rigid as yourself in their thinking.

    That is behavior that you have created, not behavior that was designed. It may be possible, but it's equally as stupid for it to be possible as it is for it to not have an event for this in the first place.



  • @pie_flavor I didn't create it.

    Brendan Eich originally created the language in about a month. So he made sure you could extend it anyway you want.

    While this does have a whole host of problems, it does allow one a lot of freedom in terms of expressiveness.

    There is always a pros and cons. I use decent JS tooling when writing pure JS or use TypeScript when possible as I prefer to have a pseudo compiler.

    Other people are fine on something more loose.

    It ultimately depends what you are trying to achieve and what you are happy with working with.

    This mindset as I said to you yesterday, that everything must be super proper is something that comes from university and isn't something that exists that strongly in the real world.


Log in to reply