javascript click button after be shure that page has completely loaded

1.7k views Asked by At

I have the website example.com and on this website is a button with the id "button1" and by clicking on this button, it opens an unknown url "example.com/unknownUrl" with the known button "buttonOnUnknownPage" on it. How can i be sure that the unknown page has finished loading and i can click "buttonOnUnknownPage"?

NOTE: "example.com" is opened in another window than the script. that means, the script don't stops running after "example.com" reloads.

I have until now used this:

// open example.com and get button1
exampleWindow = window.open("http://example.com", "_blank");
button1 = exampleWindow.document.getElementById('button1');

// clicking on button 1 opens example.com/unknownUrl
button1.click();

//and now wait 1000ms until page might be loaded
setTimeout(function() {
    buttonOnUnknownPage = exampleWindow.document.getElementById('buttonOnUnknownPage');
    buttonOnUnknownPage.click()
}, 1000);

The problem of this is, that i need to wait everytime 1000ms and can still not be sure, that "example.com/unknownUrl" was loaded.

Is there a more efficient method, to be sure that "example.com/unknownUrl" has loaded ? Something like document.onload ?

1

There are 1 answers

0
jfriend00 On BEST ANSWER

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:

  1. Get the original URL of the window (what it was before you told it to load something new).
  2. 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.
  3. 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.
  4. 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.