zzzzBov zzzzBov - 2 months ago 6x
Javascript Question

Bind document.ready to a popout window

Due to the manner in which jQuery binds the

event, code that should be simple isn't:

var w = window.open(someSameOriginLocation,'');
$(w).ready(function () { //alternatively selector could be $(w.document)
console.log('popout ready');


  • the callback executes when the parent window is ready, not the child

  • within the callback
    is a reference to

Is there a reasonably simple, cross-browser way of binding the
event (or similar) to a different window context using jQuery?


When I asked this question about 5 years ago I hadn't heard of promises. jQuery 1.7 had recently been released, and Deferred had been introduced in 1.5 earlier in the year. This predated the Promises/A+ specification, which was released just over a year later.

I say this all because at the time I had no way of recognizing jQuery's $(document).ready(...) for what it was.

It was bound as an event, and took a callback as an event, and the jQuery API treated it as an event, so I had mistakenly assumed it was an event, albeit a special one.

Document ready is not an event. It's a promise.

So with all that said, my mistake was in attempting to follow jQuery's lead and create a fancy event, when what I should have done was use a promise (never mind that they didn't exist in the JS world yet).

With all that said, supporting a document.ready-like behavior on any window reference in modern browsers is pretty simple. I have the advantage of time in that many old problems have been bugfixed away, and new browser features (such as Promise) greatly reduce the amount of effort to implement a ready function.

My solution to this problem looks like:

function ready(win) {
    return new Promise(function (resolve) {
        function checkReady() {
            if (win.document.readyState === 'complete') {

        win.document.addEventListener('DOMContentLoaded', checkReady, false);
        win.addEventListener('load', checkReady, false);

and can be used as:

ready(window).then(function () {
  //...do stuff

or if you're using window.open:

ready(open('/your/file.html', ...)).then(function () {
  //.../your/file.html is ready