为啥我的 javascript 中的 document.body 为空?

Posted

技术标签:

【中文标题】为啥我的 javascript 中的 document.body 为空?【英文标题】: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>

【问题讨论】:

我使用的是谷歌浏览器。 【参考方案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 好的,所以在撰写本文时我的回答是正确的 ;-) 感谢您提醒我,我会进行一些测试并发布更新。

以上是关于为啥我的 javascript 中的 document.body 为空?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的切换按钮无法使用 Javascript 打开我的响应式菜单?

为啥 Javascript 无法识别我的构造函数?

为啥我的 Javascript 函数只能工作几次?

为啥我的图像不会显示在 javascript 画布上?

为啥这个旧的依赖会使我的 gradle 崩溃?

为啥 NaN 大于 JavaScript 中的任何数字? [复制]