Ist es falsch, das <script> -Tag nach dem </ body> -Tag zu platzieren?

218

Wie falsch ist es, das Skript-Tag nach dem schließenden Tag des body ( </body>) zu platzieren. ?

<html>
  ....
  <body>
     ....
  </body>
  <script type="text/javascript" src="theJs.js"></script>
</html>
DanC
quelle
1
Gibt es Unterstützung dafür in modernen Browsern.
Xdrone

Antworten:

190

Es wird nicht außerhalb der Tags oder validiert . Es macht auch keinen großen Unterschied - es sei denn, Sie führen DOM-Manipulationen durch, die den IE beschädigen könnten , bevor das Body-Element vollständig geladen ist -, es kurz vor dem Schließen zu platzieren .<body><head></body>

<html>
  ....
  <body>
     ....
     <script type="text/javascript" src="theJs.js"></script>
  </body>
</html>
Andy E.
quelle
13
@epalla: Wenn Sie das Skript direkt am Ende des Body-Tags platzieren, müssen bis zum Eintreffen keine weiteren Inhalte mehr geladen werden. Es sollte also kaum einen Unterschied geben, ob Sie es außerhalb oder nur innerhalb platzieren. Sie haben dann den zusätzlichen Vorteil, dass Ihre Seite noch validiert wird. Dies war der Punkt, den ich in meiner Antwort ansprechen wollte.
Andy E
1
Ja, ich stimmte Ihnen zu, da Ihre Antwort gut ist. Ich wollte nur hinzufügen, dass es einen Grund gibt, JS am Ende der Seite anstatt im Kopf zu platzieren, wie wir es schon lange getan haben.
Matt Brunmeier
3
@PHPst: Nun, ungültiger Code kann in bestimmten Browsern Nebenwirkungen haben. In beiden Fällen sehe ich nicht, dass der Einzug, der eine Tabulatorbreite kleiner als der darüber liegende Code ist, sauberer aussieht.
Andy E
1
@PHPst: Ich würde erwarten, dass Browser damit umgehen, wenn Sie Ihren Code wirklich so schreiben möchten. Ich würde jedoch weiterhin empfehlen, Ihren Code zur Validierung zu schreiben.
Andy E
1
@technosaurus: Es gibt immer <script src="..." defer>, was in allen gängigen Browsern funktioniert (allerdings mit einem potenziell fehlerhaften Fehler in IE9 und niedriger).
Andy E
88

Ja. Nach dem End-Tag für den Body sind nur Kommentare und das End-Tag für das HTML-Element zulässig.

Browser führen möglicherweise eine Fehlerbehebung durch, aber Sie sollten sich niemals darauf verlassen.

QUentin
quelle
12
Dies ist eine bessere Antwort. Es gibt zu viele neue Browser mit mobilen Geräten, um das Risiko einzugehen, dass Sie etwas falsch machen, wenn Sie nur ein einzelnes schließendes Tag ausschneiden und einfügen müssen.
Erik Reppen
33

Wie Andy sagte, wird das Dokument nicht gültig sein, aber das Skript wird trotzdem interpretiert. Siehe das Snippet aus WebKit zum Beispiel:

void HTMLParser::processCloseTag(Token* t)
{
    // Support for really broken html.
    // we never close the body tag, since some stupid web pages close it before 
    // the actual end of the doc.
    // let's rely on the end() call to close things.
    if (t->tagName == htmlTag || t->tagName == bodyTag 
                              || t->tagName == commentAtom)
        return;
    ...
Vitalii Fedorenko
quelle
11
"Unterstützung für wirklich kaputtes HTML." - Ich denke, es sagt alles.
Diogo Kollross
8

IE erlaubt dies nicht mehr (seit Version 10, glaube ich) und wird solche Skripte ignorieren. FF und Chrome tolerieren sie immer noch, aber es besteht die Möglichkeit, dass sie dies eines Tages als nicht standardmäßig fallen lassen.

Bronx
quelle
1
Und doch macht Google dies in seinem Beispiel, wie man sich mit G + anmeldet, mit "zuletzt aktualisiert am 10. April 2014". Ich habe es von der Java-Version auf dem Server ( developer.google.com/+/quickstart/java ) erhalten, aber vermutlich ist es für alle das gleiche HTML + js.
Tom
2

Das prozedurale Einfügen von "Elementskript" nach "Elementkörper" ist "Analysefehler" gemäß dem von W3C empfohlenen Prozess . Erstellen Sie in "Tree Construction" einen Fehler und führen Sie "tokenize again" aus, um diesen Inhalt zu verarbeiten. Es ist also wie ein zusätzlicher Schritt. Nur dann kann "Script Execution" ausgeführt werden - siehe Schema-Prozess .

Alles andere "Analysefehler". Schalten Sie den "Einfügemodus" auf "in body" und verarbeiten Sie den Token erneut.

Technisch gesehen ist es per Browser ein interner Prozess, wie sie ihn markieren und optimieren.

Ich hoffe ich habe jemandem geholfen.

BG Bruno
quelle
0

Ja. Aber wenn Sie den Code außerhalb hinzufügen, ist dies höchstwahrscheinlich nicht das Ende der Welt, da die meisten Browser ihn beheben werden, aber es ist immer noch eine schlechte Praxis, sich darauf einzulassen.

Taylor Satula
quelle
0

Google empfiehlt dies tatsächlich im Hinblick auf die "CSS-Optimierung". Sie empfehlen, kritische Stile über dem Falz einzulegen und den Rest (CSS-Datei) aufzuschieben.

Beispiel:

<html>
  <head>
    <style>
      .blue{color:blue;}
    </style>
    </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
  </body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>

Siehe: https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery

Donald Porter
quelle
8
Du sollst nichts außerhalb des bodyElements platzieren. Dieser Google-Artikel rät niemandem, so etwas zu tun.
ChaseMoskal
2
Ich fürchte, diese Google-Seite sagt eigentlich genau das.
10us
6
Es scheint, als hätte diese Seite einmal so etwas empfohlen, aber nicht mehr. (Jetzt wird dynamisch mit Javascript geladen.) Die deutsche Version ist nicht aktuell und enthält noch das alte Codebeispiel.
Bodo
1
"Element Noscript" muss von RFC auch in "Element HTML" und "Element Body" sein
BG Bruno
0

Moderne Browser nehmen Skript-Tags wie folgt in den Text auf:

<body>
    <script src="scripts/main.js"></script>
</body>

Grundsätzlich bedeutet dies, dass das Skript geladen wird, sobald die Seite fertig ist, was in bestimmten Fällen nützlich sein kann (nämlich DOM-Manipulation). Ich empfehle jedoch dringend, dass Sie dasselbe Skript verwenden und es mit "defer" in das Head-Tag einfügen, da es den gleichen Effekt erzielt.

<head>
    <script src="scripts/main.js" defer></script>
</head>
Ad Charity
quelle
Was nützlich wäre, wäre, wenn scriptTags ein eventAttribut hätten, das definiert werden könnte, um zu bestimmen, wann das Skript analysiert werden soll. Sie müssen also event="load" event="DOMContentLoaded"das Skript ausführen, nachdem das DOM erstellt wurde oder event="beforeunload"auf dem Fensterereignis beforeunload. Beispiel , <script src="scripts/main.js" event="DOMContentLoaded"></script>.
1,21 Gigawatt