W3docs

Balise HTML <script>

La balise HTML <script> intègre ou charge du JavaScript. Apprenez src, async, defer, type="module", placement et attributs avec des exemples.

La balise HTML <script> déclare un script côté client — presque toujours du JavaScript — dans un document HTML. Les scripts ajoutent de l'interactivité : validation de formulaires, mises à jour dynamiques du contenu, manipulation d'images et réponse aux événements utilisateur. La balise peut soit contenir le script en ligne (entre les balises ouvrante et fermante), soit charger un fichier externe via l'attribut src. Pour un aperçu plus général de l'ajout de scripts à une page, consultez HTML scripts.

Danger

Si vous connectez un fichier externe contenant des scripts, n'incorporez pas de script dans la même balise <script>.

La balise HTML <script> peut être placée dans l'élément <head>, ainsi qu'à l'intérieur de l'élément <body>. Les scripts qui doivent être exécutés en premier sont souvent placés dans l'élément <head> avec defer, ou à la fin de l'élément <body>. La balise <script> peut être utilisée plusieurs fois dans un document HTML.

Une balise script dans un document HTML pointant vers du JavaScript externe

Syntaxe

La balise <script> se compose toujours d'une paire — une ouvrante <script> et une fermante </script>. Le code en ligne se place entre elles ; pour un fichier externe, laissez la balise vide et faites pointer src vers le fichier :

<script>
  // inline JavaScript here
  console.log("Hello from inline script");
</script>

<script src="app.js"></script>

Exemple de script en ligne

Pour sélectionner un élément HTML, JavaScript utilise couramment la méthode document.getElementById() :

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <p id="example"></p>
    <script>
      document.getElementById("example").innerHTML = "My first JavaScript code";
    </script>
  </body>
</html>

Chargement d'un script externe

Dans les projets réels, vous gardez presque toujours le JavaScript dans un fichier .js séparé et le chargez avec src. Cela garde votre HTML propre, permet au navigateur de mettre le script en cache, et permet de réutiliser le même fichier sur plusieurs pages :

<script src="app.js" defer></script>

Quelques points à noter :

  • Ne mélangez pas les deux. Lorsque src est présent, tout code écrit entre les balises est ignoré. Utilisez soit du code en ligne, soit un src, mais pas les deux dans la même balise.
  • type="text/javascript" est inutile. JavaScript est le langage de script par défaut en HTML moderne, vous pouvez donc omettre type entièrement. Ne définissez type que si vous avez réellement besoin de type="module" (voir ci-dessous).
  • charset n'a aucun effet sur les scripts externes aujourd'hui. L'encodage des caractères est pris en charge par l'en-tête HTTP Content-Type du fichier (et par l'encodage propre de la page), de sorte que l'attribut charset sur <script> est obsolète — ne vous en fiez pas.

async vs. defer

Par défaut, lorsque le navigateur rencontre un <script src="..."> lors de l'analyse du HTML, il arrête l'analyse, télécharge le script, l'exécute, puis continue. Cela bloque le rendu. Les attributs boolean async et defer résolvent ce problème — tous deux téléchargent le script en parallèle sans bloquer l'analyse — mais ils diffèrent dans le moment où le script s'exécute :

AttributBloque l'analyse ?Quand il s'exécuteOrdre
(aucun)OuiImmédiatement lors de la rencontreDans l'ordre du document
deferNonAprès l'analyse complète du HTML, juste avant DOMContentLoadedDans l'ordre du document
asyncNonDès qu'il finit de se téléchargerLe premier terminé (sans ordre garanti)
<!-- Runs after the page is parsed, in order. Safe for code that touches the DOM. -->
<script src="app.js" defer></script>

<!-- Runs as soon as it loads, order not guaranteed. Good for independent scripts
     like analytics that don't depend on other scripts or the parsed DOM. -->
<script src="analytics.js" async></script>

Utilisez defer lorsque les scripts dépendent du DOM ou les uns des autres (le cas le plus courant). Utilisez async pour les scripts autonomes et indépendants de l'ordre, tels que les pixels de suivi.

Info

async et defer sont des attributs boolean — leur simple présence les active. Écrivez-les seuls (defer), et non dans l'ancien style XHTML defer="defer". Il en va de même pour d'autres attributs boolean comme disabled et checked. Ces deux attributs sont ignorés sur les scripts en ligne (ceux sans src).

Placement du script : <head> ou fin de <body>

L'endroit où vous placez <script> est important car un script simple bloque l'analyse :

  • <head> avec defer — la recommandation moderne. Le téléchargement démarre tôt pendant que le HTML est encore analysé, et l'exécution attend que le DOM soit prêt. Vous obtenez un chargement rapide sans blocage.
  • Fin de <body> — l'approche classique. Au moment où l'analyseur atteint le script, tout le DOM existe déjà, de sorte que le script peut interroger les éléments en toute sécurité. Aucun attribut n'est nécessaire.
<head>
  <script src="app.js" defer></script>
</head>
<body>
  <!-- page content -->
</body>

Évitez un <script src> simple (sans async/defer) dans <head>, car il bloque le rendu de la page jusqu'à ce que le script soit téléchargé et exécuté.

Modules ES avec type="module"

Définir type="module" transforme le script en module ES. Les scripts de module se comportent différemment des scripts classiques :

  • Ils prennent en charge import / export, vous pouvez donc répartir le code sur plusieurs fichiers.
  • Ils sont différés par défaut — les scripts de module attendent toujours que le HTML soit analysé (pas besoin de defer).
  • Ils s'exécutent toujours en mode strict, et disposent de leur propre portée de premier niveau (les variables ne se propagent pas vers l'objet global).
<script type="module" src="main.js"></script>

<script type="module">
  import { greet } from "./greet.js";
  greet("World");
</script>

Pour prendre en charge les très anciens navigateurs qui ne comprennent pas les modules, vous pouvez associer un module à un script de repli nomodule — les navigateurs modernes exécutent le module et ignorent le repli, les plus anciens font l'inverse.

Note sur XHTML et le balisage hérité

En HTML moderne, vous n'avez pas besoin d'un attribut type, et vous n'encapsulez pas le contenu du script en ligne dans une section CDATA. L'encapsuleur //<![CDATA[ ... //]]> n'était nécessaire qu'en XHTML, où le contenu du script était analysé comme du balisage et où les caractères spéciaux tels que < et & devaient être échappés ou protégés. Si vous écrivez du HTML standard, vous pouvez l'ignorer.

Attributs

AttributValeurDescription
srcURLURL d'un fichier de script externe (relative ou absolue).
async(boolean)Le script externe est récupéré en parallèle et exécuté dès qu'il est disponible, sans bloquer l'analyse.
defer(boolean)Le script externe est récupéré en parallèle et exécuté, dans l'ordre, après l'analyse du HTML.
typetype de médiaGénéralement omis (JavaScript est la valeur par défaut). Définissez sur module pour charger un module ES.
charsetcharsetObsolète — n'a aucun effet ; l'encodage provient du Content-Type HTTP du fichier.
crossoriginanonymous | use-credentialsConfigure CORS pour la requête du script externe.
integrityhashHash Subresource Integrity utilisé pour vérifier le script récupéré.

La balise <script> prend en charge les Attributs globaux et les Attributs d'événement.

Pratique

Pratique
Quel attribut permet à un script externe de se télécharger sans bloquer l'analyse et de s'exécuter, dans l'ordre, après l'analyse du HTML ?
Quel attribut permet à un script externe de se télécharger sans bloquer l'analyse et de s'exécuter, dans l'ordre, après l'analyse du HTML ?
Was this page helpful?