Mengapa document.body null di javascript saya?

132

Ini dokumen HTML singkat saya.

Mengapa Chrome Console memperhatikan kesalahan ini:

"UnEught TypeError: Tidak dapat memanggil metode 'appendChild' of 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>
John Hoffman
sumber
Saya menggunakan Google Chrome.
John Hoffman

Jawaban:

180

Tubuh belum didefinisikan pada saat ini. Secara umum, Anda ingin membuat semua elemen sebelum Anda menjalankan javascript yang menggunakan elemen-elemen ini. Dalam hal ini Anda memiliki beberapa javascript di headbagian yang menggunakan body. Tidak keren.

Anda ingin membungkus kode ini dalam window.onloadpenangan atau menempatkannya setelah itu <body>tag (seperti yang disebutkan oleh 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>

Lihat demo .

Sergio Tulentsev
sumber
1
Terima kasih, apa maksudmu Apakah saya tidak memiliki tag tubuh?
John Hoffman
5
Halaman dibaca dari atas ke bawah dan javascript dijalankan di sepanjang jalan. Anda memiliki beberapa javascript di headbagian yang sedang dieksekusi. Tetapi bodybagian dari html, mungkin, bahkan belum diunduh. Atau sudah diunduh, tetapi masih belum dievaluasi saat ini. Jadi tidak ada di DOM.
Sergio Tulentsev
3
Bagaimana jika Anda tidak ingin menimpa beban yang ada yang ditentukan dalam file lain?
Tom Brito
1
@TomBrito: "atau menempatkannya setelah itu <body>tag"
Sergio Tulentsev
1
Sedikit terlambat, tetapi bisa juga menggunakan addEventListener untuk melampirkan listener ke jendela, tanpa mengganti yang sudah ada.
edvilme
36

Script Anda sedang dieksekusi sebelum bodyelemen bahkan dimuat.

Ada beberapa cara untuk mengatasinya.

  • Bungkus kode Anda dalam panggilan balik DOM Load:

    Bungkus logika Anda dalam acara pendengar DOMContentLoaded.

    Dengan demikian, callback akan dieksekusi ketika bodyelemen telah dimuat.

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

    Bergantung pada kebutuhan Anda, Anda dapat juga melampirkan loadpendengar acara ke windowobjek:

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

    Untuk perbedaan antara peristiwa DOMContentLoadeddan loadperistiwa, lihat pertanyaan ini .

  • Pindahkan posisi <script>elemen Anda , dan muat JavaScript terakhir:

    Saat ini, <script>elemen Anda sedang dimuat dalam <head>elemen dokumen Anda. Ini berarti bahwa itu akan dieksekusi sebelum bodydimuat. Pengembang Google merekomendasikan untuk memindahkan <script>tag ke akhir halaman Anda sehingga semua konten HTML diberikan sebelum JavaScript diproses.

    <!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>
Josh Crozier
sumber
2
Saya pikir ini lebih menyeluruh dan terkini daripada jawaban yang diterima.
theUtherSide
8

Tambahkan kode Anda ke acara onload. Jawaban yang diterima menunjukkan ini dengan benar, namun jawaban itu serta semua yang lain pada saat penulisan juga menyarankan menempatkan tag skrip setelah tag body penutup,.

Ini bukan html yang valid. Namun itu akan menyebabkan kode Anda berfungsi, karena browser terlalu baik;)

Lihat jawaban ini untuk info lebih lanjut. Apakah salah menempatkan tag <script> setelah tag </body>?

Turunkan jawaban lain karena alasan ini.

Martin Hansen
sumber
4

Atau tambahkan bagian ini

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

setelah HTML, seperti:

    <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>
Boris Bachovski
sumber
1

Browser mem-parsing html Anda dari atas ke bawah, skrip Anda berjalan sebelum tubuh dimuat. Untuk memperbaiki skrip put body.

  <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>
Emmanuel N
sumber
0

document.body belum tersedia saat kode Anda berjalan.

Apa yang dapat Anda lakukan sebagai gantinya:

var docBody=document.getElementsByTagName("body")[0];
docBody.appendChild(mySpan);
Christophe
sumber
@Jake, bisakah Anda lebih spesifik? Adakah contoh browser / versi yang tidak berfungsi?
Christophe
chrome @ 39 dan firefox @ 33
Jake
@Jake ok, jadi jawaban saya benar pada saat penulisan ;-) Terima kasih telah mengingatkan saya, saya akan melakukan beberapa pengujian dan saya akan memposting pembaruan.
Christophe