【问题标题】:Why is document.body null in my javascript?为什么我的 javascript 中的 document.body 为空?
【发布时间】:2012-04-12 14:10:18
【问题描述】:

这是我的简短 HTML 文档。

为什么 Chrome 控制台会提示此错误:

“未捕获的类型错误:无法调用null 的方法'appendChild'”?

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

【问题讨论】:

  • 我使用的是谷歌浏览器。

标签: javascript google-chrome


【解决方案1】:

此时尚未定义主体。通常,您希望在执行使用这些元素的 javascript 之前创建所有元素。在这种情况下,您在使用bodyhead 部分中有一些javascript。不酷。

您希望将此代码包装在 window.onload 处理程序中,或将其放在 &lt;body&gt; 标记之后(如 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>

See demo.

【讨论】:

  • 谢谢您,您是什么意思?我没有body标签吗?
  • 页面从上到下读取,并沿途执行javascript。您在正在执行的head 部分中有一些javascript。但是body 部分的 html 可能还没有被下载。或者已下载,但此时仍未对其进行评估。所以它在 DOM 中不存在。
  • 如果您不想覆盖另一个文件中定义的现有 onload 怎么办?
  • @TomBrito: "或者把它放在&lt;body&gt;标签之后"
  • 有点晚了,但也可以使用 addEventListener 将监听器附加到窗口,而不用替换现有的。
【解决方案2】:

您的脚本在 body 元素甚至还没有加载之前就被执行了。

有几种方法可以解决这个问题。

  • 将您的代码包装在 DOM 加载回调中:

    将您的逻辑封装在 DOMContentLoaded 的事件侦听器中。

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

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

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

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

    DOMContentLoadedload 事件之间的区别,see this question

  • 移动&lt;script&gt;元素的位置,最后加载JavaScript:

    现在,您的 &lt;script&gt; 元素正在加载到文档的 &lt;head&gt; 元素中。这意味着它将在body 加载之前执行。 Google developers 建议将 &lt;script&gt; 标记移到页面末尾,以便在处理 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>
    

【讨论】:

  • 我认为这比公认的答案更彻底和最新。
【解决方案3】:

将您的代码添加到 onload 事件。接受的答案正确地表明了这一点,但是在撰写本文时,该答案以及所有其他答案也建议将脚本标记放在结束正文标记之后。

这不是有效的 html。但是它会导致你的代码工作,因为浏览器太友好了;)

查看此答案了解更多信息 Is it wrong to place the <script> tag after the </body> tag?

出于这个原因,否决了其他答案。

【讨论】:

    【解决方案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,您的脚本在加载正文之前运行。修复正文后的放置脚本。

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

        【讨论】:

        • @Jake 你能说得更具体点吗?浏览器/版本不起作用的任何示例?
        • chrome@39 和 firefox@33
        • @Jake 好的,所以在撰写本文时我的回答是正确的 ;-) 感谢您提醒我,我会进行一些测试并发布更新。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-19
        • 1970-01-01
        • 1970-01-01
        • 2015-03-06
        • 2012-10-08
        • 2016-09-04
        • 2018-06-26
        相关资源
        最近更新 更多