How to detect URL change in JavaScript

How to check if URL has changed in JavaScript? For example, sites like GitHub that use AJAX will add page information after the # character to create a unique URL without reloading the page. What is the best way to determine if this URL is changing?

  • Is the onload event onload ?
  • Is there an event handler for the URL?
  • Or do you need the url checked every second to detect a change?
+124
javascript ajax
Jun 17. '11 at 18:45
source share
14 answers

In modern browsers (IE8 +, FF3.6 +, Chrome), you can simply listen to the hashchange event on window .

In some older browsers, you need a timer that constantly checks location.hash . If you use jQuery, there is a plugin that does just that.

+91
Jun 17 '11 at 18:50
source share

use this code

 window.onhashchange = function() { //code } 

with jQuery

 $(window).bind('hashchange', function() { //code }); 
+68
May 7 '16 at 17:18
source share

With jquery (and the plugin) you can do

 $(window).bind('hashchange', function() { /* things */ }); 

http://benalman.com/projects/jquery-hashchange-plugin/

Otherwise, yes, you will need to use setInterval and check for a change in the hash event (window.location.hash)

Update! Simple draft

 function hashHandler(){ this.oldHash = window.location.hash; this.Check; var that = this; var detect = function(){ if(that.oldHash!=window.location.hash){ alert("HASH CHANGED - new has" + window.location.hash); that.oldHash = window.location.hash; } }; this.Check = setInterval(function(){ detect() }, 100); } var hashDetection = new hashHandler(); 
+55
Jun 17 '11 at 18:49
source share

EDIT after a little research:

For some reason, it seems that I was fooled by the documentation provided in the Mozilla documentation. The popstate event (and its onpopstate callback function) does not fire whenever pushState() or replaceState() called in replaceState() . Therefore, the original answer does not apply in all cases.

However, there is a way around this by correcting functions according to @ alpha123 :

 var pushState = history.pushState; history.pushState = function () { pushState.apply(history, arguments); fireEvents('pushState', arguments); // Some event-handling function }; 

Original answer

Given that the title of this question is β€œHow to Detect URL Changes,” the answer when you want to know when the full path (and not just the hash binding) changes is that you can listen to the popstate event:

 window.onpopstate = function(event) { console.log("location: " + document.location + ", state: " + JSON.stringify(event.state)); }; 

Link for popstate in Mozilla Docs

Currently (January 2017), support for popstate is supported by 92% of browsers worldwide.

+42
Jan 24 '17 at 9:56 on
source share

What I wanted was to be able to add a locationchange to event listeners. With this modification we can do something like this

 window.addEventListener('locationchange', function(){ console.log('location changed!'); }) 

In contrast, window.addEventListener('hashchange',()=>{}) will only work if the part after the hashtag in the URL changes and window.addEventListener('popstate',()=>{}) not always working.

This modification, similar to the Christian answer , modifies the object of history to add some features.

By default, there is a popstate event, but no events for pushstate and replacestate .

This modifies these three functions so that they all fire a custom locationchange event for you to use, as well as pushstate and replacestate events if you want to use them:

 /* These are the modifications: */ history.pushState = ( f => function pushState(){ var ret = f.apply(this, arguments); window.dispatchEvent(new Event('pushState')); window.dispatchEvent(new Event('locationchange')); return ret; })(history.pushState); history.replaceState = ( f => function replaceState(){ var ret = f.apply(this, arguments); window.dispatchEvent(new Event('replaceState')); window.dispatchEvent(new Event('locationchange')); return ret; })(history.replaceState); window.addEventListener('popstate',()=>{ window.dispatchEvent(new Event('locationchange')) }); 
+36
Oct 15 '18 at 2:47
source share

Add a hash change event listener!

 window.addEventListener('hashchange', function(e){console.log('hash changed')}); 

Or, to listen to all URL changes:

 window.addEventListener('popstate', function(e){console.log('url changed')}); 

This is better than something like the code below, because only one thing can exist in window.onhashchange, and you might rewrite the code of another user.

 // Bad code example window.onhashchange = function() { // Code that overwrites whatever was previously in window.onhashchange } 
+19
Jun 01 '17 at 23:26
source share

this solution worked for me:

 var oldURL = ""; var currentURL = window.location.href; function checkURLchange(currentURL){ if(currentURL != oldURL){ alert("url changed!"); oldURL = currentURL; } oldURL = window.location.href; setInterval(function() { checkURLchange(window.location.href); }, 1000); } checkURLchange(); 
+7
Apr 05 '16 at 23:37
source share

Despite the old question, the Location-bar project is very useful.

 var LocationBar = require("location-bar"); var locationBar = new LocationBar(); // listen to all changes to the location bar locationBar.onChange(function (path) { console.log("the current url is", path); }); // listen to a specific change to location bar // eg Backbone builds on top of this method to implement // it simple parametrized Backbone.Router locationBar.route(/some\-regex/, function () { // only called when the current url matches the regex }); locationBar.start({ pushState: true }); // update the address bar and add a new entry in browsers history locationBar.update("/some/url?param=123"); // update the address bar but don't add the entry in history locationBar.update("/some/url", {replace: true}); // update the address bar and call the 'change' callback locationBar.update("/some/url", {trigger: true}); 
+4
May 20 '15 at 2:14
source share

To listen to URL changes, see below:

 window.onpopstate = function(event) { console.log("location: " + document.location + ", state: " + JSON.stringify(event.state)); }; 

Use this style if you want to stop / remove the listener after a certain condition.

 window.addEventListener('popstate', function(e) { console.log('url changed') }); 
+3
Dec 20 '17 at 9:01
source share

Take a look at the jQuery unload function. He handles everything.

https://api.jquery.com/unload/

An unload event is dispatched to a window element when a user navigates from a page. This may mean one of many. The user could click the link to leave the page, or type a new URL in the address bar. The forward and reverse buttons will trigger an event. Closing the browser window will trigger the event. Even reloading the page will first create an unload event.

 $(window).unload( function(event) { alert("navigating"); } ); 
+1
Jan 6 '16 at 16:30
source share

When creating a small Chrome extension, I ran into the same problem as the additional problem: sometimes pages change, but not URLs.

For example, just go to the Facebook homepage and click the "Home" button. You reload the page, but the URL does not change (single-page application style).

In 99% of cases, we design websites so that we can receive events from Frameworks such as Angular, React, Vue, etc.

BUT , in my case with the Chrome extension (in Vanilla JS), I had to listen to an event that will fire for each β€œpage change” that can usually be detected when the URL changes, but sometimes it’s not.

My home solution was the following:

 listen(window.history.length); var oldLength = -1; function listen(currentLength) { if (currentLength != oldLength) { // Do your stuff here } oldLength = window.history.length; setTimeout(function () { listen(window.history.length); }, 1000); } 

Thus, basically the leoneckert solution applied to the window history will change when the page changes in a single-page application.

Not rocket science, but the purest solution I have found, given that we are only checking integer equality here, and not large objects or the entire DOM.

+1
Apr 11 '18 at 10:27
source share
 window.addEventListener("beforeunload", function (e) { // do something }, false); 
0
May 01 '16 at 12:14
source share

You start a new setInterval on every call without canceling the previous one - perhaps you only meant setTimeout

-one
Jan 26 '17 at 13:00
source share

The answer below comes from here (with the old javascript syntax (without arrow function, support for IE 10+)): stack overflow

 (function() { if (typeof window.CustomEvent === "function") return false; // If not IE function CustomEvent(event, params) { params = params || {bubbles: false, cancelable: false, detail: null}; var evt = document.createEvent("CustomEvent"); evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); return evt; } window.CustomEvent = CustomEvent; })(); (function() { history.pushState = function (f) { return function pushState() { var ret = f.apply(this, arguments); window.dispatchEvent(new CustomEvent("pushState")); window.dispatchEvent(new CustomEvent("locationchange")); return ret; }; }(history.pushState); history.replaceState = function (f) { return function replaceState() { var ret = f.apply(this, arguments); window.dispatchEvent(new CustomEvent("replaceState")); window.dispatchEvent(new CustomEvent("locationchange")); return ret; }; }(history.replaceState); window.addEventListener("popstate", function() { window.dispatchEvent(new CustomEvent("locationchange")); }); })(); 
-one
Aug 21 '19 at 8:06
source share



All Articles