The monitoring of some other window as it changes location is fairly complicated and the reason it's complicated is that each time the other window loads a new document, the entire window
state is cleared and all event listeners are wiped out and a whole new document is created. So, you can't install an event listener once and keep using it because it gets wiped out each time a new link is clicked and the page location is changed.
It is further complicated by the fact that the process of creating a new window for a particular URL will (in some browsers) first load a URL called about:blank
and then load the real URL causing your monitoring to sometimes detect the loading of the about:blank internal URL, not the real URL you want to monitor. IE (even new versions) is particular bad for this (no surprise).
So, it is possible to track the loading of these external windows, but it takes some hacking to get it to work. The hacking requires these steps:
- Get the original URL of the window (what it was before you told it to load something new).
- Wait until the window.location.href value for that window is no longer the original URL. This signifies that the window has now started to load its new URL.
- Once it is loading the new URL, then wait until the window shows that it has a
.addEventListener
property. For some unknown reason, newly created windows in IE don't yet have this property. That means you can't install a load
event handler on a newly create window. Instead, you have to wait until that property is available and then you can install the load
event handler.
- When the
.addEventListener
property is available, see if the document is already done loading. If so, proceed with your DOM operation. If not, then register an event handler for when the document is done loading.
I've created a function call monitorWindowLoad()
for carrying out these steps above:
function monitorWindowLoad(win, origURL, fn) {
log("monitorWindowLoad: origURL = " + origURL);
function windowInitiated() {
// at this point, we know the new URL is in window.location.href
// so the loading of the new window has started
// unfortunately for us, IE does not necessarily have a fully formed
// window object yet so we have to wait until the addEventListener
// property is available
checkCondition(function() {
return !!win.addEventListener;
}, windowListen);
}
// new window is ready for a listener
function windowListen() {
if (win.document.readyState === "complete") {
log("found readyState");
fn();
} else {
log("no readyState, setting load event handler");
win.addEventListener("load", fn);
}
}
if (origURL) {
// wait until URL changes before starting to monitor
// the changing of the URL will signal that the new loading window has been initialized
// enough for us to monitor its load status
checkCondition(function() {
return win.location.href !== origURL;
}, windowInitiated);
} else {
windowInitiated();
}
}
// Check a condition. If immediately true, then call completeFn
// if not immediately true, then keep testing the condition
// on an interval timer until it is true
function checkCondition(condFn, completeFn) {
if (condFn()) {
completeFn();
} else {
var timer = setInterval(function() {
if (condFn()) {
clearInterval(timer);
completeFn();
}
}, 1);
}
}
This function can then be used to click successive links in several loading pages like this:
function go() {
// open new window
var exampleWindow = window.open("window2.html");
monitorWindowLoad(exampleWindow, "about:blank", function() {
var loc = exampleWindow.location.href;
clickButton(exampleWindow, "button2");
monitorWindowLoad(exampleWindow, loc, function() {
loc = exampleWindow.location.href;
clickButton(exampleWindow, "button3");
monitorWindowLoad(exampleWindow, loc, function() {
// last page loaded now
});
});
});
}
There's actually working demo of this concept here. This loads a file named window1a.html. The Javascript in that page opens a new window for window2.html, and when that is loaded, it clicks a specific link in that window. Clicking that link opens window3.html and when that is loaded, it clicks a link in that window which then opens window4.html. You should end up with two windows open (window1a.html and window4.html). window1a.html will contain a log of the various events it carried out.
The script in window1.html doesn't know any of the URLs. It's just clicking links and monitoring when the newly loaded window has loaded so it can click the next link and so on.