W3docs

Tag HTML <script>

Il tag HTML <script> incorpora o collega JavaScript in una pagina. Scopri src, async vs defer, type="module", posizionamento e attributi con esempi.

Il tag HTML <script> dichiara script lato client — quasi sempre JavaScript — in un documento HTML. Gli script aggiungono interattività: validazione dei moduli, aggiornamenti dinamici dei contenuti, manipolazione delle immagini e risposta agli eventi utente. Il tag può contenere lo script inline (tra i tag di apertura e chiusura) oppure caricare un file esterno tramite l'attributo src. Per una panoramica più ampia sull'aggiunta di script a una pagina, consulta HTML scripts.

Pericolo

Se colleghi un file esterno con degli script, non incorporare script nello stesso tag <script>.

Il tag HTML <script> può essere posizionato nell'elemento <head>, così come all'interno dell'elemento <body>. Gli script che devono essere eseguiti per primi vengono spesso inseriti nell'elemento <head> con defer, o alla fine dell'elemento <body>. Il tag <script> può essere utilizzato più volte in un documento HTML.

Un tag script all'interno di un documento HTML che collega a JavaScript esterno

Sintassi

Il tag <script> viene sempre in coppia — un <script> di apertura e un </script> di chiusura. Il codice inline va tra di essi; per un file esterno, lascia il tag vuoto e punta src al file:

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

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

Esempio di script inline

Per selezionare un elemento HTML, JavaScript usa comunemente il metodo 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>

Caricamento di uno script esterno

Nei progetti reali si mantiene quasi sempre JavaScript in un file .js separato e lo si carica con src. Questo mantiene il codice HTML pulito, consente al browser di mettere in cache lo script e permette di riutilizzare lo stesso file su più pagine:

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

Alcune cose da tenere a mente:

  • Non mescolare i due approcci. Quando src è presente, qualsiasi codice scritto tra i tag viene ignorato. Usa il codice inline oppure un src, non entrambi nello stesso tag.
  • type="text/javascript" non è necessario. JavaScript è il linguaggio di scripting predefinito nell'HTML moderno, quindi puoi omettere completamente type. Imposta type solo quando hai effettivamente bisogno di type="module" (vedi sotto).
  • charset non ha effetto sugli script esterni oggi. La codifica dei caratteri viene ricavata dall'intestazione HTTP Content-Type del file (e dalla codifica della pagina stessa), quindi l'attributo charset su <script> è obsoleto — non farci affidamento.

async vs. defer

Per impostazione predefinita, quando il browser incontra un <script src="..."> durante l'analisi dell'HTML, si ferma, scarica lo script, lo esegue e solo allora continua. Questo blocca il rendering. Gli attributi boolean async e defer risolvono il problema — entrambi scaricano lo script in parallelo senza bloccare l'analisi — ma differiscono nel momento in cui lo script viene eseguito:

AttributoBlocca l'analisi?Quando viene eseguitoOrdine
(nessuno)Immediatamente quando viene incontratoNell'ordine del documento
deferNoDopo che l'HTML è completamente analizzato, appena prima di DOMContentLoadedNell'ordine del documento
asyncNoNon appena termina il downloadChi finisce prima (fuori ordine)
<!-- 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>

Usa defer quando gli script dipendono dal DOM o l'uno dall'altro (il caso comune). Usa async per script indipendenti e senza dipendenze d'ordine, come i pixel di tracciamento.

Informazione

async e defer sono attributi boolean — la loro semplice presenza li attiva. Scrivili nella forma semplice (defer), non nel vecchio stile XHTML defer="defer". Lo stesso vale per altri attributi boolean come disabled e checked. Entrambi gli attributi vengono ignorati sugli script inline (quelli senza src).

Posizionamento dello script: <head> vs. fine del <body>

Il punto in cui si inserisce <script> è importante perché uno script semplice blocca l'analisi:

  • <head> con defer — la raccomandazione moderna. Il download inizia presto mentre l'HTML è ancora in fase di analisi, e l'esecuzione attende che il DOM sia pronto. Si ottiene un caricamento veloce senza blocchi.
  • Fine del <body> — l'approccio classico. Quando il parser raggiunge lo script, l'intero DOM esiste già, quindi lo script può interrogare gli elementi in sicurezza. Non è necessario alcun attributo.
<head>
  <script src="app.js" defer></script>
</head>
<body>
  <!-- page content -->
</body>

Evita un semplice <script src> (senza async/defer) nel <head>, poiché blocca il rendering della pagina fino al download ed esecuzione dello script.

Moduli ES con type="module"

Impostando type="module" lo script diventa un modulo ES. Gli script modulo si comportano diversamente dagli script classici:

  • Supportano import / export, quindi puoi suddividere il codice su più file.
  • Sono differiti per impostazione predefinita — gli script modulo attendono sempre che l'HTML venga analizzato (non è necessario defer).
  • Vengono sempre eseguiti in strict mode e hanno il proprio scope di livello superiore (le variabili non trapelano nell'oggetto globale).
<script type="module" src="main.js"></script>

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

Per supportare browser molto vecchi che non comprendono i moduli, puoi abbinare un modulo a uno script di fallback nomodule — i browser moderni eseguono il modulo e ignorano il fallback, quelli più vecchi fanno il contrario.

Nota su XHTML e markup legacy

Nell'HTML moderno non è necessario un attributo type, né occorre racchiudere il contenuto dello script inline in una sezione CDATA. Quel wrapper //<![CDATA[ ... //]]> era rilevante solo in XHTML, dove il contenuto dello script veniva analizzato come markup e i caratteri speciali come < e & dovevano essere escapati o protetti. Se stai scrivendo HTML standard, puoi ignorarlo.

Attributi

AttributoValoreDescrizione
srcURLURL di un file di script esterno (relativo o assoluto).
async(boolean)Lo script esterno viene scaricato in parallelo ed eseguito non appena disponibile, senza bloccare l'analisi.
defer(boolean)Lo script esterno viene scaricato in parallelo ed eseguito, in ordine, dopo l'analisi dell'HTML.
typetipo mediaDi solito omesso (JavaScript è il valore predefinito). Impostato su module per caricare un modulo ES.
charsetcharsetObsoleto — non ha effetto; la codifica proviene dall'intestazione HTTP Content-Type del file.
crossoriginanonymous | use-credentialsConfigura CORS per la richiesta dello script esterno.
integrityhashHash Subresource Integrity utilizzato per verificare lo script scaricato.

Il tag <script> supporta gli Attributi Globali e gli Attributi Evento.

Esercitazione

Pratica
Quale attributo consente a uno script esterno di scaricarsi senza bloccare l'analisi ed eseguirsi, in ordine, dopo che l'HTML è stato analizzato?
Quale attributo consente a uno script esterno di scaricarsi senza bloccare l'analisi ed eseguirsi, in ordine, dopo che l'HTML è stato analizzato?
Was this page helpful?