How to detect URL change in JavaScript

2019-01-02 20:27发布

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?

13条回答
回忆,回不去的记忆
2楼-- · 2019-01-02 20:32

You are starting a new setInterval at each call, without cancelling the previous one - probably you only meant to have a setTimeout

查看更多
皆成旧梦
3楼-- · 2019-01-02 20:33

With jquery (and a plug-in) you can do

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

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

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

Update! A 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();
查看更多
其实,你不懂
4楼-- · 2019-01-02 20:33

use this code

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

with jQuery

$(window).bind('hashchange', function() {
     //code
});
查看更多
唯独是你
5楼-- · 2019-01-02 20:35

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'll possibly be overwriting someone else's code.

// Bad code example

window.onhashchange = function() { 
     // Code that overwrites whatever was previously in window.onhashchange  
}
查看更多
墨雨无痕
6楼-- · 2019-01-02 20:36

While doing a little chrome extension, I faced the same problem with an additionnal problem : Sometimes, the page change but not the URL.

For instance, just go yo Facebook Home page, and click on 'Home' button. You will reload the page but the URL won't change (one-page app style).

99% of the time, we are developping websites so we can get those events from Frameworks like Angular, React, Vue etc..

BUT, in my case of a Chrome extension (in Vanilla JS), I had to listen to an event that will trigger for each "page change", which can generally be caught by URL changed, but sometimes it doesn't.

My homemade 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;
  setInterval(function () {
    listen(window.history.length);
  }, 1000);
}

So basically the leoneckert solution, applied to window history, which will change when a page change in a single page app.

Not rocket science, but cleanest solution I found, considering we are only checking an integer equality here, and not bigger objects or the whole DOM.

查看更多
深知你不懂我心
7楼-- · 2019-01-02 20:41

Although an 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
// e.g. Backbone builds on top of this method to implement
// it's 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});
查看更多
登录 后发表回答