Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if URL has changed after hash in JavaScript

How can I check if a URL has changed in JavaScript? For example, websites like GitHub, which use AJAX, will append page information after a # symbol to create a unique URL without reloading the page. What is the best way to detect if this URL changes?

  • Is the onload event called again?
  • Is there an event handler for the URL?
  • Or must the URL be checked every second to detect a change?
like image 703
AJ00200 Avatar asked Jun 17 '11 18:06

AJ00200


People also ask

How to detect a URL change?

The MutationObserver() function is used to detect or watch the changes made on the DOM tree. It simply detects the DOM element changes and also URL changes on the single-page website like React JS and Angular JS.

How do I get the current URL?

The current URL can be obtained by using the 'URL' property of the Document object which contains information about the current URL. The 'URL' property returns a string with the full location of the current page, along with containing the string having the HTTP protocol such as ( http://).


2 Answers

I wanted to be able to add locationchange event listeners. After the modification below, we'll be able to do it, like this

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

In contrast, window.addEventListener('hashchange',()=>{}) would only fire if the part after a hashtag in a url changes, and window.addEventListener('popstate',()=>{}) doesn't always work.

This modification, similar to Christian's answer, modifies the history object to add some functionality.

By default, before these modifications, there's a popstate event, but there are no events for pushstate, and replacestate.

This modifies these three functions so that all fire a custom locationchange event for you to use, and also pushstate and replacestate events if you want to use those.

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')) }); 

Note:

We're creating a closure, old = (f=>function new(){f();...})(old) replaces old with a new function that contains the previous old saved within it (old is not run at this moment, but it will be run inside of new)

like image 189
aljgom Avatar answered Sep 21 '22 17:09

aljgom


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

In some old browsers, you need a timer that continually checks location.hash. If you're using jQuery, there is a plugin that does exactly that.

Example

Below I undo any URL change, to keep just the scrolling:

<script type="text/javascript">   if (window.history) {     var myOldUrl = window.location.href;     window.addEventListener('hashchange', function(){       window.history.pushState({}, null, myOldUrl);     });   } </script> 

Note that above used history-API is available in Chrome, Safari, Firefox 4+, and Internet Explorer 10pp4+

like image 32
phihag Avatar answered Sep 24 '22 17:09

phihag