Почему document.body пусто в моем JavaScript? - PullRequest
112 голосов
/ 29 марта 2012

Вот мой краткий 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>

Ответы [ 6 ]

153 голосов
/ 29 марта 2012

Тело еще не определено. В общем, вы хотите создать все элементы перед выполнением 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>

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

25 голосов
/ 15 ноября 2015

Ваш скрипт выполняется еще до того, как элемент 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>
    
8 голосов
/ 29 марта 2012

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

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

См. Этот ответ для получения дополнительной информации Не правильно ли размещать тег после тега ?

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

4 голосов
/ 29 марта 2012

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

<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>
1 голос
/ 29 марта 2012

Браузер анализирует ваш HTML сверху вниз, ваш скрипт запускается до загрузки тела. Чтобы исправить поставить скрипт после тела.

  <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>
0 голосов
/ 05 ноября 2013

document.body пока не доступен, когда ваш код выполняется.

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

var docBody=document.getElementsByTagName("body")[0];
docBody.appendChild(mySpan);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...