5

I want to add a listener to "before URL change" event, with access to the old URL. window.onbeforeunload does not fire if the page does not reload (AJAX driven pages).

This happens on YouTube video pages, when you click on another video in the right navigation column, for example.

I have read this post, which polls window.location. But this does not capture the old URL.

This is for a Chrome extension. I'm looking for a way to detect before URL change in javascript.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
Keven Wang
  • 1,208
  • 17
  • 28
  • 1
    Give the [History API](https://developer.mozilla.org/en-US/docs/Web/API/window.history) a shot. – Joseph Aug 25 '13 at 00:13
  • try searching for local storage – Charaf JRA Aug 25 '13 at 00:15
  • You might be looking for the `beforeunload` event coupled with the History API – Martin Jespersen Aug 25 '13 at 00:38
  • You want to use this in a popup window? Or using a greesemonkey script? Your missing some key information in your post. – Menelaos Aug 25 '13 at 00:46
  • @JosephtheDreamer I'm programming a chrome extension. Is there an alternative for Chrome? – Keven Wang Aug 26 '13 at 23:41
  • @meewoK I'm programming in chrome extension, but I'm looking for a generic way to do this in javascript in Chrome. I hope to execute some functions whenever a new flash video is loaded. The beforeunload does not fire for some cases, where url changes without a page reload. – Keven Wang Aug 26 '13 at 23:42
  • 1
    You've specifically said that you want to detect navigation on YouTube. In that case, see [this answer](http://stackoverflow.com/a/18398921/938089) to [this question](http://stackoverflow.com/questions/18397962/chrome-extension-is-not-loading-on-browser-navigation-at-youtube "Chrome extension is not loading on browser navigation at YouTube"). – Rob W Sep 23 '13 at 13:44

2 Answers2

4

For AJAX-driven pages that use the history API (most of them, including YouTube), you can splice into history.pushState.

For Chrome, the old url will be in the spf-referer property. (Also, the location.href will still be set to the old URL while pushState is firing, too.)

So code like this will work:

var H               = window.history;
var oldPushState    = H.pushState;
H.pushState         = function (state) {
    if (typeof H.onpushstate == "function") {
        H.onpushstate ({state: state} );
    }
    return oldPushState.apply (H, arguments);
}
window.onpopstate = history.onpushstate = function (evt) {
    console.log ("Old URL: ", evt.state["spf-referer"]);
}

Note that, because you need to override the target page's pushState function, you must inject this code from your content script.

Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
2

If you're writing a Chrome extension, you can listen to the onUpdated event which is fired when a tab url is changed. More information here https://developer.chrome.com/extensions/tabs.html#event-onUpdated.

Ryan Dao
  • 321
  • 1
  • 4
  • 13
  • I am aware of the tab onUpdate. However, you can only detect with background script, when the url is updated. I'm looking for a way to detect in content script, while still having access to the old url. – Keven Wang Aug 25 '13 at 03:48
  • 2
    Then you can use the method of polling `window.location` as mentioned in your question. For having access to the old url, just save it as a global variable, or save it to localStorage. Youtube uses History API, so it'll not reload your content script when navigating to another video. – Ryan Dao Aug 25 '13 at 04:57