Why does document's readystate change from "complete" to "loading"?

Viewed 449

Please take a look at the following code:

this.detachedWin = window.open(window.origin + "/@/tab","Detached","menubar=0,toolbar=0,personalbar=0,status=0");
  
this.doc = this.detachedWin.document;

setInterval(() => {
  console.log(this.doc === this.detachedWin.document,this.detachedWin.document.readyState);
  this.doc = this.detachedWin.document;
}, 10);

JSFiddle

If you take a look at your console log, you see something like this:

enter image description here

I don't underestand why the ready state of document is "complete" at the first time and what is the reason it changes to loading after that? I expect that the ready state to be "loading" for the first time.

1 Answers

First "complete" happens with blank window, and then it changes location to provided URL.

Note that remote URLs won't load immediately. When window.open() returns, the window always contains about:blank. The actual fetching of the URL is deferred and starts after the current script block finishes executing. The window creation and the loading of the referenced resource are done asynchronously.

developer.mozilla.org

Simplified window opening flow

  1. window.open()
  2. Immediately loaded, because nothing to load: "loading"
  3. Immediately become interactive, because it's empty: "interactive"
  4. Blank window is ready: "completed"
  5. Set window.location explicitly or implicitly
  6. Redirect to URL: "loading"
  7. Window become interactive: "interactive"
  8. Window is ready: "completed"

Full flow with all steps for window opening you can find in specification.

To see how it works, check example:

const openMe = () => { 
  this.detachedWin = window.open("", "Detached","menubar=0,toolbar=0,personalbar=0,status=0");

  setTimeout(() => {
    console.log("loading happen now")
    this.detachedWin.location = window.origin + "/@/tab"
  }, 1000);

  this.doc = this.detachedWin.document;
  setInterval(() => {
    console.log(this.doc === this.detachedWin.document, this.detachedWin.document.readyState);
    this.doc = this.detachedWin.document;
  }, 10);
}
<button onclick="openMe()">Open window</button>

Related