Javascript에서 document.body가 null 인 이유는 무엇입니까?


132

다음은 간단한 HTML 문서입니다.

Chrome 콘솔에서이 오류를 알리는 이유 :

"Catch되지 않은 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>

Chrome을 사용하고 있습니다.
존 호프만

답변:


180

본문은 아직 정의되지 않았습니다. 일반적으로 이러한 요소를 사용하는 자바 스크립트를 실행하기 전에 모든 요소를 ​​작성하려고합니다. 이 경우 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
페이지는 위에서 아래로 읽히고 자바 스크립트는 도중에 실행됩니다. head실행중인 섹션에 자바 스크립트가 있습니다. 그러나 bodyhtml의 일부는 아직 다운로드되지 않았습니다. 또는 다운로드되었지만 현재 평가되지는 않습니다. 따라서 DOM에는 존재하지 않습니다.
Sergio Tulentsev

3
다른 파일에 정의 된 기존 온로드를 재정의하지 않으려면 어떻게해야합니까?
Tom Brito

1
@TomBrito는 "또는 배치 <body> 태그"
세르지오 Tulentsev

1
조금 늦었지만 addEventListener를 사용하여 기존 리스너를 바꾸지 않고 리스너를 창에 연결할 수도 있습니다.
edvilme

36

body요소가로드 되기 전에 스크립트가 실행되고 있습니다.

이 문제를 해결하는 몇 가지 방법이 있습니다.

  • DOM로드 콜백으로 코드를 래핑하십시오.

    의 이벤트 리스너에 로직을 래핑하십시오 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> 는 자바 스크립트가 처리되기 전에 모든 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 이벤트에 코드를 추가하십시오. 수락 된 답변은 이것을 올바르게 보여 주지만 글을 쓰는 시점의 모든 답변뿐만 아니라 스크립트 태그를 닫는 본문 태그 뒤에 넣는 것이 좋습니다.

유효한 HTML이 아닙니다. 그러나 브라우저가 너무 친절하기 때문에 코드가 작동합니다.)

자세한 내용은이 답변을 참조하십시오 . <body> 태그를 </ 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을 위에서 아래로 구문 분석하고 본문이로드되기 전에 스크립트가 실행됩니다. 본문 뒤에 put 스크립트를 수정합니다.

  <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 ok, 그래서 글을 쓸 때 대답이 정확했다 ;-) 경고 해 주셔서 감사합니다. 테스트를 해보고 업데이트를 게시 할 것입니다.
Christophe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.