Est-ce mal de placer la balise <script> après la balise </body>?

219

À quel point est-il mal de placer la balise de script après la balise de fermeture du corps ( </body>). ?

<html>
  ....
  <body>
     ....
  </body>
  <script type="text/javascript" src="theJs.js"></script>
</html>
DanC
la source
1
Existe-t-il un support pour cela dans les navigateurs modernes.
Xdrone

Réponses:

191

Il ne sera pas validé en dehors des balises <body>ou <head>. Cela ne fera pas non plus de différence - à moins que vous ne fassiez des manipulations DOM qui pourraient casser IE avant que l'élément de corps ne soit complètement chargé - pour le mettre juste avant la fermeture </body>.

<html>
  ....
  <body>
     ....
     <script type="text/javascript" src="theJs.js"></script>
  </body>
</html>
Andy E
la source
13
@epalla: si vous placez le script à la fin de la balise body, il n'y a plus d'autre contenu à charger au moment où il y arrive, il ne devrait donc pas y avoir de grande différence entre le placer à l'extérieur ou juste à l'intérieur. Vous avez alors l'avantage supplémentaire de valider votre page, ce qui était le point que j'essayais de souligner dans ma réponse.
Andy E
1
Oui, j'étais d'accord avec toi car ta réponse est bonne. Je voulais juste ajouter qu'il y a une raison pour mettre JS au bas de la page plutôt que dans la tête comme nous le faisons depuis longtemps.
Matt Brunmeier
3
@PHPst: eh bien, un code invalide peut être sujet à des effets secondaires dans certains navigateurs. Quoi qu'il en soit, je ne vois pas comment son indentation étant d'une largeur de tabulation inférieure au code ci-dessus, il semble plus propre.
Andy E
1
@PHPst: Je m'attendrais à ce que les navigateurs le gèrent si vous voulez vraiment écrire votre code de cette façon. Je recommanderais quand même d'écrire votre code pour valider.
Andy E
1
@technosaurus: il y en a toujours <script src="..." defer>, qui fonctionne dans tous les principaux navigateurs (mais avec un bogue potentiellement cassant dans IE9 et inférieur).
Andy E
88

Oui. Seuls les commentaires et la balise de fin de l'élément html sont autorisés après la balise de fin du corps.

Les navigateurs peuvent effectuer une récupération d'erreur, mais vous ne devez jamais en dépendre.

Quentin
la source
12
C'est une meilleure réponse. Il y a trop de nouveaux navigateurs sur le marché avec le mobile entrant en jeu pour risquer de le faire mal quand il vous suffit de couper et coller une seule balise de fermeture.
Erik Reppen
33

Comme l'a dit Andy , le document ne sera pas valide, mais néanmoins le script sera toujours interprété. Voir l' extrait de WebKit par exemple:

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
la source
11
"Support pour html vraiment cassé." - Je pense que ça dit tout.
Diogo Kollross
8

IE ne permet plus cela (depuis la version 10, je crois) et ignorera ces scripts. FF et Chrome les tolèrent toujours, mais il y a des chances qu'un jour ils abandonnent cela comme non standard.

Bronx
la source
1
Et pourtant, Google le fait dans son exemple de la procédure de connexion G +, avec "la dernière mise à jour le 10 avril 2014". Je l'ai obtenu de la version pour Java sur le serveur ( developers.google.com/+/quickstart/java ) mais je suppose que c'est le même HTML + js pour tous.
Tom
2

Insérez procéduralement le "script d'élément" après "le corps de l'élément" est "erreur d'analyse" par le processus recommandé par le W3C . Dans "Tree Construction", créez une erreur et exécutez "tokenize again" pour traiter ce contenu. C'est donc comme une étape supplémentaire. Ce n'est qu'alors que l'on peut exécuter "Script Execution" - voir processus de schéma .

Tout autre "erreur d'analyse". Basculez le "mode d'insertion" sur "dans le corps" et retraitez le jeton.

Techniquement, par navigateur, c'est un processus interne, comment ils le marquent et l'optimisent.

J'espère avoir aidé quelqu'un.

BG Bruno
la source
0

Oui. Mais si vous ajoutez le code à l'extérieur, ce ne sera probablement pas la fin du monde car la plupart des navigateurs le corrigeront, mais c'est toujours une mauvaise pratique d'y entrer.

Taylor Satula
la source
0

Google le recommande en fait en ce qui concerne «l'optimisation CSS». Ils recommandent d'intégrer les styles critiques au-dessus du pli et de reporter le reste (fichier css).

Exemple:

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

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

Donald Porter
la source
8
Vous n'êtes pas censé mettre des choses en dehors de l' bodyélément. Cet article Google ne conseille à personne de faire une telle chose.
ChaseMoskal
2
J'ai peur que la page Google ne dise exactement cela.
10us
6
Il semble qu'à un moment donné, cette page a recommandé une telle chose, mais plus maintenant. (Maintenant, il y a un chargement dynamique avec javascript.) La version allemande n'est pas à jour et contient toujours l'ancien exemple de code.
bodo
1
"element noscript" doit être par RFC dans "element html" et "element body" aussi
BG Bruno
0

Les navigateurs modernes prendront des balises de script dans le corps comme suit:

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

Fondamentalement, cela signifie que le script sera chargé une fois la page terminée, ce qui peut être utile dans certains cas (notamment la manipulation DOM). Cependant, je vous recommande fortement de prendre le même script et de le mettre dans la balise head avec "defer", car cela donnera le même effet.

<head>
    <script src="scripts/main.js" defer></script>
</head>
Ad Charity
la source
Ce qui serait utile, c'est si les scriptbalises avaient un eventattribut qui pourrait être défini pour déterminer quand analyser le script. Vous devez donc event="load" event="DOMContentLoaded"exécuter le script après la création du DOM ou event="beforeunload"sur l' beforeunloadévénement window . Exemple, <script src="scripts/main.js" event="DOMContentLoaded"></script>.
1,21 gigawatts le