0

document.write seems to figure out on its own when to write to the head and when to write to the body.

For example, it writes <style> and <script> to the head and <div> to the body.

Can this automatic behavior be avoided and let the programmer decide what goes where?

I experimented this with iframes. Unfortunately, the internal code box here doesn't seem to support interacting with iframes, so please see it in JSFiddle.

var theiframe=document.getElementById('testing'), output=document.getElementById('output'), thebody=document.getElementById('output_body'), thehead=document.getElementById('output_head'), thebody=document.getElementById('output_body');
console.clear();
console.group('Testing');
theiframe.contentWindow.document.open();
theiframe.contentWindow.document.writeln("<script>var foo1='head';<\/script>");
theiframe.contentWindow.document.writeln("<script>var foo2='body';<\/script>");
theiframe.contentWindow.document.close();
console.log(theiframe.contentWindow.document.documentElement);
thehead.value = theiframe.contentWindow.document.head.innerHTML;
thebody.value = theiframe.contentWindow.document.body.innerHTML;
console.groupEnd();
textarea {width: 50%}
Iframe:
<br /><iframe id="testing"></iframe>
<hr>
Iframe's head:
<br /><textarea id="output_head"><</textarea>
<hr>
Iframe's body:
<br /><textarea id="output_body"><</textarea>
LWC
  • 804
  • 8
  • 26

2 Answers2

0

Based on another answer, document.write can be controlled by specifically using it to declare either or both <head> and <body>.

For example, document.write('<style>p {font-size: 1em}<\/style>') goes to head, but document.write('<body><style>p {font-size: 1em}<\/style><\/body>') goes to body.

Likewise, document.write('<script>var a=2;<\/script>') goes to head, but document.write('<body><script>var a=2;<\/script><\/body>') goes to body.

As mentioned in that answer, it will of course not work on elements that simply can't be in the head, like <span> or <div>.

See full demonstration in JSFiddle (which supports interaction with iframes).

var theiframe=document.getElementById('testing'), output=document.getElementById('output'), thebody=document.getElementById('output_body'), thehead=document.getElementById('output_head'), thebody=document.getElementById('output_body');
console.clear();
console.group('Testing');
theiframe.contentWindow.document.open();
theiframe.contentWindow.document.write("<head>");
theiframe.contentWindow.document.write("<script>var foo1='head';<\/script>");
theiframe.contentWindow.document.write("<\/head>");
theiframe.contentWindow.document.write("<body>");
theiframe.contentWindow.document.write("<script>var foo2='body';<\/script>");
theiframe.contentWindow.document.write("</body>");
theiframe.contentWindow.document.close();
console.log(theiframe.contentWindow.document.documentElement);
thehead.value = theiframe.contentWindow.document.head.innerHTML;
thebody.value = theiframe.contentWindow.document.body.innerHTML;
console.groupEnd();
textarea {width: 50%}
Iframe:
<br /><iframe id="testing"></iframe>
<hr>
Iframe's head:
<br /><textarea id="output_head"><</textarea>
<hr>
Iframe's body:
<br /><textarea id="output_body"><</textarea>
LWC
  • 804
  • 8
  • 26
0

document.write writes the HTML to whatever the next bit of the document is.

It follows the normal rules of HTML. The fact you are using document.write doesn't matter.

If you have an HTML document that looks like this:

<style>p { ... }</style>
<div>...</div>

Then it implicitly creates the html element and the head element at which point a style element is valid and it insert the style element there.

Then you have a div element. This cannot exist inside the head, so it implicitly ends the head element and opens the body element.

A script element is allowed in both the head and the body so it will end up wherever you put it.

This is just how HTML works.


Can this automatic behavior be avoided and let the programmer decide what goes where?

Some HTML parsers will let you get away with explicitly starting the body and then inserting a style element. You can't use a hack like that to put a div in the head though.

<body>
<style>p { ... }</style>
<div>...</div>

You can also use DOM manipulation (appendChild et al) to insert elements in places they don't belong and bypass the HTML parsing rules.


Intentionally generating an invalid DOM really isn't a good idea. If you're trying to come up with some kind of hack that needs it, you should probably rethink your entire approach.

Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205