Почему document.body null в моем javascript?

Вот мой короткий документ HTML.

Почему Chrome Console отмечает эту ошибку:

"Uncaught TypeError: Не удается вызвать метод appendChild из 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>

Ответ 1

Тело еще не определено на этом этапе. В общем, вы хотите создать все элементы перед выполнением javascript, который использует эти элементы. В этом случае у вас есть javascript в разделе head, который использует body. Не круто.

Вы хотите обернуть этот код в обработчик window.onload или поместить его после тега <body> (как указано e-bacho 2.0).

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

    <script type="text/javascript">
      window.onload = function() {
        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>

См. демонстрацию.

Ответ 2

Ваш скрипт выполняется еще до того, как элемент body был загружен.

Есть несколько способов обойти это.

  • Оберните ваш код в обратный вызов DOM Load:

    Оберните свою логику в прослушивателе событий для DOMContentLoaded.

    При этом обратный вызов будет выполнен после загрузки элемента body.

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

    В зависимости от ваших потребностей, вы можете альтернативно присоединить слушатель события load к объекту window:

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

    О разнице между DOMContentLoaded и load см. Этот вопрос.

  • Переместите позицию вашего элемента <script> и загрузите JavaScript последним:

    Прямо сейчас ваш элемент <script> загружается в элемент <head> вашего документа. Это означает, что оно будет выполнено до загрузки body. Разработчики Google рекомендуют переместить теги <script> в конец вашей страницы, чтобы весь контент HTML отображался до обработки JavaScript.

    <!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>
    

Ответ 3

Добавьте свой код в событие onload. Принятый ответ показывает это правильно, однако этот ответ, как и все остальные на момент написания статьи, также предлагает поместить тег script после закрытия тега body.

Это недействительно html. Однако это заставит ваш код работать, потому что браузеры слишком добры;)

См. этот ответ для получения дополнительной информации Неправильно ли разместить <script> тег после </body> тег?

По этой причине были переданы другие ответы.

Ответ 4

Или добавьте эту часть

<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, например:

    <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>

Ответ 5

Браузер анализирует ваш html сверху вниз, ваш script запускается до загрузки тела. Зафиксировать поместите script после тела.

  <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>

Ответ 6

document.body пока недоступен, когда ваш код работает.

Что вы можете сделать вместо этого:

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

Ответ 7

Похоже, самый быстрый способ определить, доступен ли document.body с помощью MutationObserver, как показано на fooobar.com/info/1559843/...