Living Standard — Last Updated 9 June 2025
APIs for dynamically inserting markup into the document interact with the parser, and thus their behavior varies depending on whether they are used with HTML documents (and the HTML parser) or XML documents (and the XML parser).
Document
objects have a throw-on-dynamic-markup-insertion counter,
which is used in conjunction with the create an element for the token algorithm to
prevent custom element constructors from being
able to use document.open()
, document.close()
, and document.write()
when they are invoked by the parser.
Initially, the counter must be set to zero.
document = document.open()
Support in all current engines.
Causes the Document
to be replaced in-place, as if it was a new
Document
object, but reusing the previous object, which is then returned.
The resulting Document
has an HTML parser associated with it, which can be given
data to parse using document.write()
.
The method has no effect if the Document
is still being parsed.
Throws an "InvalidStateError
" DOMException
if the
Document
is an XML document.
Throws an "InvalidStateError
" DOMException
if the
parser is currently executing a custom element constructor.
window = document.open(url, name, features)
Works like the window.open()
method.
Document
objects have an active parser was aborted boolean, which is
used to prevent scripts from invoking the document.open()
and document.write()
methods (directly or indirectly)
after the document's active parser has been aborted. It is initially false.
The document open steps, given a document, are as follows:
If document is an XML document, then throw
an "InvalidStateError
" DOMException
.
If document's throw-on-dynamic-markup-insertion counter is greater
than 0, then throw an "InvalidStateError
"
DOMException
.
Let entryDocument be the entry global object's associated Document
.
If document's origin is not
same origin to entryDocument's origin, then throw a
"SecurityError
" DOMException
.
If document has an active parser whose script nesting level is greater than 0, then return document.
This basically causes document.open()
to
be ignored when it's called in an inline script found during parsing, while still letting it
have an effect when called from a non-parser task such as a timer callback or event handler.
Similarly, if document's unload counter is greater than 0, then return document.
This basically causes document.open()
to
be ignored when it's called from a beforeunload
, pagehide
, or unload
event
handler while the Document
is being unloaded.
If document's active parser was aborted is true, then return document.
This notably causes document.open()
to
be ignored if it is called after a navigation has started, but
only during the initial parse. See issue
#4723 for more background.
If document's node navigable is non-null and document's node navigable's ongoing navigation is a navigation ID, then stop loading document's node navigable.
For each shadow-including inclusive descendant node of document, erase all event listeners and handlers given node.
If document is the associated
Document
of document's relevant global object, then
erase all event listeners and handlers given document's relevant
global object.
Replace all with null within document.
If document is fully active, then:
Let newURL be a copy of entryDocument's URL.
If entryDocument is not document, then set newURL's fragment to null.
Run the URL and history update steps with document and newURL.
Set document's is initial about:blank
to
false.
If document's iframe load in progress flag is set, then set document's mute iframe load flag.
Set document to no-quirks mode.
Create a new HTML parser and associate it with document. This is a
script-created parser (meaning that it can be closed by the document.open()
and document.close()
methods, and that the tokenizer will wait for
an explicit call to document.close()
before emitting an
end-of-file token). The encoding confidence is
irrelevant.
Set the insertion point to point at just before the end of the input stream (which at this point will be empty).
Update the current document readiness of document to "loading
".
This causes a readystatechange
event to fire, but the event is actually unobservable to author code, because of the previous
step which erased all event listeners and
handlers that could observe it.
Return document.
The document open steps do not affect whether a Document
is ready for post-load tasks or completely loaded.
The open(unused1,
unused2)
method must return the result of running the document open
steps with this.
The unused1 and
unused2 arguments are ignored, but kept in the IDL to allow code that calls the
function with one or two arguments to continue working. They are necessary due to Web IDL
overload resolution algorithm rules, which would throw a TypeError
exception for such calls had the arguments not been there. whatwg/webidl issue #581 investigates
changing the algorithm to allow for their removal. [WEBIDL]
The open(url,
name, features)
method must run these steps:
If this is not fully active, then throw an
"InvalidAccessError
" DOMException
.
Return the result of running the window open steps with url, name, and features.
document.close()
Support in all current engines.
Closes the input stream that was opened by the document.open()
method.
Throws an "InvalidStateError
" DOMException
if the
Document
is an XML document.
Throws an "InvalidStateError
" DOMException
if the
parser is currently executing a custom element constructor.
The close()
method must run the following
steps:
If this is an XML document, then throw
an "InvalidStateError
" DOMException
.
If this's throw-on-dynamic-markup-insertion counter is greater
than zero, then throw an "InvalidStateError
"
DOMException
.
If there is no script-created parser associated with this, then return.
Insert an explicit "EOF" character at the end of the parser's input stream.
If this's pending parsing-blocking script is not null, then return.
Run the tokenizer, processing resulting tokens as they are emitted, and stopping when the tokenizer reaches the explicit "EOF" character or spins the event loop.
document.write()
document.write(...text)
Support in all current engines.
In general, adds the given string(s) to the Document
's input stream.
This method has very idiosyncratic behavior. In some cases, this method can
affect the state of the HTML parser while the parser is running, resulting in a DOM
that does not correspond to the source of the document (e.g. if the string written is the string
"
" or "