Perché document.body è null nel mio javascript?


132

Ecco il mio breve documento HTML.

Perché Chrome Console rileva questo errore:

"Uncaught TypeError: Impossibile chiamare il metodo 'appendChild' di 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>

Sto usando Google Chrome.
John Hoffman,

Risposte:


180

Il corpo non è stato ancora definito a questo punto. In generale, si desidera creare tutti gli elementi prima di eseguire javascript che utilizza questi elementi. In questo caso hai qualche javascript nella headsezione che usa body. Non fico.

Si desidera racchiudere questo codice in un window.onloadgestore o inserirlo dopo il <body>tag (come indicato da 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>

Vedi la demo .


1
Grazie, cosa intendi? Non ho un body tag?
John Hoffman,

5
La pagina viene letta dall'alto verso il basso e javascript viene eseguito lungo la strada. Hai qualche javascript nella headsezione che viene eseguita. Ma bodyparte dell'html, forse, non è stato ancora scaricato. Oppure viene scaricato, ma non è ancora valutato a questo punto. Quindi non esiste nel DOM.
Sergio Tulentsev,

3
Cosa succede se non si desidera sovrascrivere un onload esistente definito in un altro file?
Tom Brito,

1
@TomBrito: "o posizionalo dopo il <body>tag"
Sergio Tulentsev

1
Un po 'in ritardo, ma potrebbe anche utilizzare addEventListener per collegare il listener alla finestra, senza sostituire quelli esistenti.
edvilme,

36

Lo script viene eseguito prima ancora che l' bodyelemento sia stato caricato.

Ci sono un paio di modi per risolvere questo problema.

  • Inserisci il tuo codice in un callback di DOM Load:

    Avvolgi la tua logica in un listener di eventi per DOMContentLoaded.

    In tal modo, il callback verrà eseguito quando l' bodyelemento è stato caricato.

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

    A seconda delle esigenze, in alternativa è possibile collegare un loadlistener di eventi windowall'oggetto:

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

    Per la differenza tra gli eventi DOMContentLoadede load, vedere questa domanda .

  • Sposta la posizione del tuo <script>elemento e carica JavaScript per ultimo:

    In questo momento, il tuo <script>elemento viene caricato <head>nell'elemento del documento. Ciò significa che verrà eseguito prima del bodycaricamento. Gli sviluppatori di Google consiglia di spostare i <script>tag alla fine della pagina in modo che tutto il contenuto HTML venga visualizzato prima dell'elaborazione di JavaScript.

    <!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
Penso che questo sia più approfondito e attuale della risposta accettata.
theUtherSide

8

Aggiungi il tuo codice all'evento onload. La risposta accettata lo mostra correttamente, tuttavia quella risposta e tutte le altre al momento della stesura suggeriscono anche di inserire il tag script dopo il tag body di chiusura,.

Questo non è html valido. Tuttavia farà funzionare il tuo codice, perché i browser sono troppo gentili;)

Vedi questa risposta per maggiori informazioni È sbagliato posizionare il tag <script> dopo il tag </body>?

Ha votato verso il basso altre risposte per questo motivo.


4

O aggiungi questa parte

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

dopo l'HTML, come:

    <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

Il browser analizza il tuo html dall'alto verso il basso, lo script viene eseguito prima del caricamento del corpo. Per correggere put script dopo 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>

0

document.body non è ancora disponibile quando viene eseguito il codice.

Cosa puoi fare invece:

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

@Jake potresti essere più specifico? Qualche esempio di browser / versione in cui non funziona?
Christophe,

chrome @ 39 e firefox @ 33
Jake

@Jake ok, quindi la mia risposta era corretta al momento della stesura ;-) Grazie per avermi avvisato, farò alcuni test e posterò un aggiornamento.
Christophe
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.