为什么我的JavaScript中的document.body为null?


132

这是我的简短HTML文档。

为什么Chrome控制台注意到此错误:

“未捕获的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>

我正在使用Google Chrome。
约翰·霍夫曼

Answers:


180

目前尚未定义主体。通常,您需要在执行使用这些元素的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>

参见演示


1
谢谢,你什么意思?我没有身体标签吗?
约翰·霍夫曼

5
该页面是从上至下阅读的,并且在执行过程中会执行javascript。您head正在执行的部分中有一些JavaScript 。但是body,也许还没有下载html的一部分。或已下载,但目前仍未评估。因此它在DOM中不存在。
塞尔吉奥·图伦采夫2012年

3
如果您不想覆盖另一个文件中定义的现有onload,该怎么办?
汤姆·布里托

1
@TomBrito:“还是把它之后<body>标记”
塞尔吉奥Tulentsev

1
有点晚了,但是也可以使用addEventListener将侦听器附加到窗口,而不替换现有的侦听器。
edvilme '19

36

您的脚本在执行之前 body元素加载就已。

有两种方法可以解决此问题。

  • 将代码包装在DOM Load回调中:

    在事件监听器中包装逻辑 DOMContentLoaded

    这样,将在body元素加载后执行回调。

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

    根据需要,您可以选择将load事件侦听器附加到window对象:

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

    有关DOMContentLoadedload事件之间的区别,请参见此问题

  • 移动<script>元素的位置,最后加载JavaScript:

    现在,您的<script>元素正在加载到<head>文档的元素中。这意味着它将在body加载之前执行。Google开发人员建议将<script>标记移到页面的末尾,以便在处理JavaScript之前呈现所有HTML内容。

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

2
我认为这比公认的答案更全面和最新。
theUtherSide

8

将代码添加到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>

1

浏览器从上到下解析您的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

document.body 代码运行时尚不可用。

您可以做什么:

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

@Jake您能更具体一点吗?浏览器/版本无法正常运行的任何示例?
Christophe

chrome @ 39和firefox @ 33
Jake

@Jake好的,所以在撰写本文时,我的回答是正确的;-)感谢您的提醒,我将进行一些测试,并发布更新。
Christophe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.