如何检查URL是否在JavaScript中发生了变化?例如,像GitHub这样使用AJAX的网站,会在#符号后附加页面信息,以创建唯一的URL,而无需重新加载页面。检测该URL是否发生变化的最佳方法是什么?

是否再次调用onload事件? 是否有URL的事件处理程序? 或者必须每秒钟检查URL以检测更改?


当前回答

虽然这是一个老问题,但位置栏项目非常有用。

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

其他回答

在做一点chrome扩展时,我遇到了一个额外的问题:有时,页面变化而不是URL。

例如,只要进入Facebook主页,然后点击“主页”按钮。你将重新加载页面,但URL不会改变(单页应用程序样式)。

99%的时间里,我们在开发网站,这样我们就可以从Angular、React、Vue等框架中获取这些事件。

但是,在我的Chrome扩展(在香草JS)的情况下,我不得不听一个事件,将触发每个“页面变化”,这通常可以通过URL变化捕获,但有时它不会。

我自己的解决方案如下:

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

leoneckert解决方案,应用于窗口历史记录,当单页应用中的页面改变时,窗口历史记录也会改变。

这不是火箭科学,而是我发现的最干净的解决方案,考虑到我们在这里只检查一个整数相等,而不是更大的对象或整个DOM。

看看jQuery的卸载函数。它能处理所有的事情。

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

当用户导航离开页面时,卸载事件被发送到窗口元素。这可能意味着许多事情之一。用户可以点击一个链接离开页面,或者在地址栏中输入一个新的URL。前进和后退按钮将触发事件。关闭浏览器窗口将触发该事件。即使是重新加载页面也会首先创建卸载事件。

$(window).unload(
    function(event) {
        alert("navigating");
    }
);

当点击链接将你重定向到同一域名的不同页面时,这些似乎都不起作用。因此,我提出了自己的解决方案:

let pathname = location.pathname;
window.addEventListener("click", function() {
    if (location.pathname != pathname) {
        pathname = location.pathname;
        // code
    }
});

编辑:您还可以检查popstate事件(如果用户返回一个页面)

window.addEventListener("popstate", function() {
    // code
});

最好的祝愿,

微积分

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

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

or

window.addEventListener('hashchange', function() { 
  //code  
});

window.addEventListener('popstate', function() { 
  //code  
});

与jQuery

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

$(window).bind('popstate', function() {
     //code
});

下面的答案来自这里(使用旧的javascript语法(没有箭头函数,支持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"));
  });
})();