[javascript] Why is document.body null in my javascript?

Here is my brief HTML document.

Why is Chrome Console noting this error:

"Uncaught TypeError: Cannot call method 'appendChild' of null"?

<html>
<head>
    <title>Javascript Tests</title>

    <script type="text/javascript">

        var mySpan = document.createElement("span");
        mySpan.innerHTML = "This is my span!";

        mySpan.style.color = "red";
        document.body.appendChild(mySpan);

        alert("Why does the span change after this alert? Not before?");

    </script>
</head>
<body>

</body>
</html>

This question is related to javascript google-chrome

The answer is


Browser parses your html from top down, your script runs before body is loaded. To fix put script after body.

  <html>
  <head>
       <title> Javascript Tests </title> 
  </head>
 <body>
 </body>
  <script type="text/javascript">

    var mySpan = document.createElement("span");
    mySpan.innerHTML = "This is my span!";

    mySpan.style.color = "red";
    document.body.appendChild(mySpan);

    alert("Why does the span change after this alert? Not before?");

</script>
</html>

document.body is not yet available when your code runs.

What you can do instead:

var docBody=document.getElementsByTagName("body")[0];
docBody.appendChild(mySpan);

Your script is being executed before the body element has even loaded.

There are a couple ways to workaround this.

  • Wrap your code in a DOM Load callback:

    Wrap your logic in an event listener for DOMContentLoaded.

    In doing so, the callback will be executed when the body element has loaded.

    document.addEventListener('DOMContentLoaded', function () {
        // ...
        // Place code here.
        // ...
    });
    

    Depending on your needs, you can alternatively attach a load event listener to the window object:

    window.addEventListener('load', function () {
        // ...
        // Place code here.
        // ...
    });
    

    For the difference between between the DOMContentLoaded and load events, see this question.

  • Move the position of your <script> element, and load JavaScript last:

    Right now, your <script> element is being loaded in the <head> element of your document. This means that it will be executed before the body has loaded. Google developers recommends moving the <script> tags to the end of your page so that all the HTML content is rendered before the JavaScript is processed.

    <!DOCTYPE html>
    <html>
    <head></head>
    <body>
      <p>Some paragraph</p>
      <!-- End of HTML content in the body tag -->
    
      <script>
        <!-- Place your script tags here. -->
      </script>
    </body>
    </html>
    

Or add this part

<script type="text/javascript">

    var mySpan = document.createElement("span");
    mySpan.innerHTML = "This is my span!";

    mySpan.style.color = "red";
    document.body.appendChild(mySpan);

    alert("Why does the span change after this alert? Not before?");

</script>

after the HTML, like:

    <html>
    <head>...</head>
    <body>...</body>
   <script type="text/javascript">
        var mySpan = document.createElement("span");
        mySpan.innerHTML = "This is my span!";

        mySpan.style.color = "red";
        document.body.appendChild(mySpan);

        alert("Why does the span change after this alert? Not before?");

    </script>

    </html>

Add your code to the onload event. The accepted answer shows this correctly, however that answer as well as all the others at the time of writing also suggest putting the script tag after the closing body tag, .

This is not valid html. However it will cause your code to work, because browsers are too kind ;)

See this answer for more info Is it wrong to place the <script> tag after the </body> tag?

Downvoted other answers for this reason.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to google-chrome

SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81 SameSite warning Chrome 77 What's the net::ERR_HTTP2_PROTOCOL_ERROR about? session not created: This version of ChromeDriver only supports Chrome version 74 error with ChromeDriver Chrome using Selenium Jupyter Notebook not saving: '_xsrf' argument missing from post How to fix 'Unchecked runtime.lastError: The message port closed before a response was received' chrome issue? Selenium: WebDriverException:Chrome failed to start: crashed as google-chrome is no longer running so ChromeDriver is assuming that Chrome has crashed WebDriverException: unknown error: DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser How to make audio autoplay on chrome How to handle "Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first." on Desktop with Chrome 66?