What is innerHTML, and how does document.write work?

Consider the following:

<!DOCTYPE HTML> <html lang="en-US"> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="script.js"></script> <script type="text/javascript"> document.write('<script type="text/javascript" src="script2.js"></scr'+'ipt>'); document.write('<script type="text/javascript" src="script3.js"></scr'+'ipt>'); console.log(document.getElementsByTagName("script").length + " Scripts"); console.log(document.head.innerHTML); </script> </head> <body> </body> </html> 

What do you expect from console.log? I hope you come to one of two results that I would expect: 4 Scripts , and both existing or all four script tags shown in innerHTML head ( document.write , could also be written to the body, so you can expect script tags to be introduced as children of the body).

The thing is that in Chrome and IE11 the first script tag added through document.write is displayed in the innerHTML head, and the second is not, and the result of the DOM query is 3 Scripts .

Can anyone comment?

+6
source share
4 answers

Providing the ability to render work in Chrome:

In the script, I have script.js: x = 1, script2.js: y = 1 and script3.js: z = 1

 <!DOCTYPE HTML> <html lang="en-US"> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="script.js"></script> <script type="text/javascript"> console.log("after 1",x); document.write('<script type="text/javascript" src="script2.js"><\/script>'); document.write('<script type="text/javascript" src="script3.js"><\/script>'); setTimeout(function() { console.log(document.getElementsByTagName("script").length + " Scripts"); console.log(document.head.innerHTML); console.log("after 3",x,y,z) },100); // the milliseconds MAY need to be higher over the net </script> </head> <body> </body> 

Result:

 4 Scripts <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="script.js"></script> <script type="text/javascript"> document.write('<script type="text/javascript" src="script2.js"><\/script>'); document.write('<script type="text/javascript" src="script3.js"><\/script>'); setTimeout(function() { console.log(document.getElementsByTagName("script").length + " Scripts"); console.log(document.head.innerHTML); console.log("after 3",x,y,z) },10) </script><script type="text/javascript" src="script2.js"></script><script type="text/javascript" src="script3.js"></script> after 3 1 1 1 
+2
source

Using document.write() is the old and wrong way , you should use the DOM:

 <!DOCTYPE HTML> <html lang="en-US"> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="script.js"></script> <script type="text/javascript"> // Child 1 var script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'script2.js'; document.getElementsByTagName('head')[0].appendChild(script); //Child 2 var script = document.createElement('script'); script.type = 'text/javascript'; script.src = 'script3.js'; document.getElementsByTagName('head')[0].appendChild(script); console.log(document.getElementsByTagName("script").length + " Scripts"); console.log(document.head.innerHTML); </script> </head> <body> </body> </html> 

He returns 4 Scripts

+1
source

One possible explanation for counting 3 is that scripts added through document.write are executed synchronously. So:

  • The script engine executes a script block containing document.write

    • The script engine adds the first script to the DOM.
    • The script engine does not add a second script to the DOM - it must wait for the first script to load and execute. In the end, the first script can do document.write("<!--");
    • Script engine returns counter 3
  • The script engine loads the first script and executes it.

  • The script engine adds a second script to the DOM, loads it, and executes it.

Keep in mind that JavaScript is single-threaded. This prevents the script tags generated by document.write from being executed until the script that generates the script tags ends.

+1
source

This is because you write the script tag inside another script tag and end up creating invalid markup (I might be wrong, but my theory matches what you see)

 1---> <script type="text/javascript" src="script.js"></script> 2---> <script type="text/javascript"> <script type="text/javascript" src="script2.js"> </script> 3---> <script type="text/javascript" src="script3.js"> </script> </script> 

may be?!

UPDATE

After a little game, I agree with @mplungjan, it's a matter of time. This works as expected. Script score is now displayed 5

 <!DOCTYPE HTML> <html lang="en-US"> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="script.js"></script> <script type="text/javascript"> document.write('<script type="text/javascript" src="script2.js"></scr'+'ipt>'); document.write('<script type="text/javascript" src="script3.js"></scr'+'ipt>'); </script> <script type="text/javascript"> console.log(document.getElementsByTagName("script").length + " Scripts"); console.log(document.head.innerHTML); </script> </head> <body> </body> </html> 
0
source

Source: https://habr.com/ru/post/984937/


All Articles