How to detect if URL has changed after hash in JavaScript

后端 未结 17 1437
無奈伤痛
無奈伤痛 2020-11-22 17:02

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 w

相关标签:
17条回答
  • 2020-11-22 17:44

    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});
    
    0 讨论(0)
  • 2020-11-22 17:44

    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 to the Facebook Homepage, and click on the '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;
      setTimeout(function () {
        listen(window.history.length);
      }, 1000);
    }
    

    So basically the leoneckert solution, applied to window history, which will change when a page changes 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.

    0 讨论(0)
  • 2020-11-22 17:45

    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();
    
    0 讨论(0)
  • 2020-11-22 17:45

    The answer below comes from here(with old javascript syntax(no arrow function, support IE 10+)): https://stackoverflow.com/a/52809105/9168962

    (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"));
      });
    })();
    
    0 讨论(0)
  • 2020-11-22 17:47
    window.addEventListener("beforeunload", function (e) {
        // do something
    }, false);
    
    0 讨论(0)
  • 2020-11-22 17:52

    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();
    
    0 讨论(0)
提交回复
热议问题