Znacznik HTMLStruktura dokumentu

<script>

Osadza kod JavaScript w stronie albo wczytuje go z pliku, żeby dodać stronie zachowanie.

Wyświetlanie
none
Znacznik zamykający
Wymagany
Dozwolona zawartość
Kod JavaScript albo dane, zależnie od type. Przy src element pozostaje pusty
Na tej stronie

Przykład

#
HTML
<p>Ukończone dziś lekcje: <strong id="count">0</strong></p>
<button type="button" id="done">Ukończ lekcję</button>

<script>
  const count = document.getElementById('count');
  const button = document.getElementById('done');

  button.addEventListener('click', () => {
    count.textContent = Number(count.textContent) + 1;
  });
</script>
Podgląd

Skrypt stoi pod przyciskiem, więc w chwili uruchomienia oba elementy już istnieją na stronie.

Definicja i zastosowanie

#

Element <script> uruchamia JavaScript. Kod możesz wpisać bezpośrednio między znacznikami albo wskazać plik w atrybucie src. W tym drugim przypadku element musi pozostać pusty, a treść wpisana w środku zostanie zignorowana.

Zwykły skrypt bez dodatkowych atrybutów zatrzymuje budowanie strony: parser czeka, aż kod się pobierze i wykona, i dopiero potem czyta dalszy HTML. Stąd dwa typowe problemy: skrypt w nagłówku opóźnia pokazanie strony, a kod nie znajduje elementów, które stoją w pliku niżej, bo jeszcze nie istnieją. Rozwiązaniem jest atrybut defer, typ module albo umieszczenie skryptu na końcu <body>.

Atrybut type decyduje, czym jest zawartość. Bez niego to zwykły skrypt, module oznacza moduł JavaScript z import i export, a typy danych, np. application/json czy application/ld+json, sprawiają, że przeglądarka niczego nie uruchamia, tylko przechowuje dane dla innych skryptów lub wyszukiwarek.

Znacznik zamykający </script> jest obowiązkowy, także przy src. Zapis <script src="app.js" /> w HTML nie działa: ukośnik zostanie zignorowany, a przeglądarka potraktuje dalszą część strony jako kod skryptu.

Składnia

#
Składnia
<script src="plik.js" defer></script>

<script>
  // kod JavaScript
</script>

Atrybuty

#
  • src

    URL

    Adres pliku z kodem JavaScript. Przeglądarka zapisuje taki plik w pamięci podręcznej i może go użyć ponownie na innych podstronach. Pamiętaj o znaczniku zamykającym, nawet gdy element jest pusty.
  • defer

    atrybut logiczny

    Pobiera skrypt w tle, nie wstrzymując parsera, i uruchamia go dopiero po wczytaniu całego HTML, tuż przed zdarzeniem DOMContentLoaded. Kilka skryptów z defer wykona się w kolejności, w jakiej stoją w kodzie. Działa tylko razem z src.
  • async

    atrybut logiczny

    Pobiera skrypt w tle i uruchamia go od razu po pobraniu, nawet jeśli strona jeszcze się wczytuje. Kolejność wykonania nie jest gwarantowana, więc async pasuje do niezależnych skryptów, takich jak statystyki odwiedzin, a nie do kodu, który korzysta z innych plików. W zwykłych skryptach działa tylko razem z src.
  • type

    brak | module | importmap | typ danych

    Rodzaj zawartości. Pominięty oznacza zwykły JavaScript, więc pisanie type="text/javascript" jest zbędne. module tworzy moduł, importmap definiuje mapę importów dla modułów, a inne wartości, np. application/ld+json, zamieniają element w blok danych, którego przeglądarka nie wykonuje.
  • type="module"

    moduł JavaScript

    Uruchamia kod jako moduł: możesz w nim używać import i export, działa w trybie ścisłym, a jego zmienne nie trafiają do zakresu globalnego. Moduły domyślnie zachowują się jak skrypty z defer. Zwykle nie zadziałają po otwarciu pliku HTML prosto z dysku (file://), więc uruchamiaj stronę przez lokalny serwer.
  • nomodule

    atrybut logiczny

    Skrypt z tym atrybutem uruchomią tylko przeglądarki, które nie znają modułów. Służył do dostarczania wersji awaryjnej dla bardzo starych przeglądarek. Dziś moduły obsługuje każda popularna przeglądarka, więc rzadko go potrzebujesz.
  • integrity

    skrót kryptograficzny, np. `sha384-…`

    Subresource Integrity: przeglądarka sprawdza, czy pobrany plik ma dokładnie taki skrót, jaki podałeś. Jeśli plik został zmieniony, na przykład podmieniony na serwerze CDN, skrypt się nie wykona. Przy plikach z innej domeny wymagany jest też atrybut crossorigin.
  • crossorigin

    anonymous | use-credentials

    Pobiera skrypt z innej domeny w trybie CORS. Jest wymagany przy integrity dla plików z zewnętrznych serwerów, a do tego sprawia, że błędy z takiego skryptu trafiają do window.onerror z pełnym opisem, a nie jako ogólne „Script error.”. Serwer musi odpowiedzieć odpowiednim nagłówkiem CORS.

Element obsługuje też wszystkie atrybuty globalne, takie jak class, id, style czy hidden.

Atrybuty w praktyce

#

src

URL

Adres pliku z kodem JavaScript. Przeglądarka zapisuje taki plik w pamięci podręcznej i może go użyć ponownie na innych podstronach. Pamiętaj o znaczniku zamykającym, nawet gdy element jest pusty.

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

defer

atrybut logiczny

Pobiera skrypt w tle, nie wstrzymując parsera, i uruchamia go dopiero po wczytaniu całego HTML, tuż przed zdarzeniem DOMContentLoaded. Kilka skryptów z defer wykona się w kolejności, w jakiej stoją w kodzie. Działa tylko razem z src.

HTML
<head>
  <script src="/js/menu.js" defer></script>
  <script src="/js/app.js" defer></script>
</head>

Oba pliki pobierają się równolegle, a uruchamiają po kolei, najpierw menu.js, potem app.js, gdy HTML jest już gotowy.

async

atrybut logiczny

Pobiera skrypt w tle i uruchamia go od razu po pobraniu, nawet jeśli strona jeszcze się wczytuje. Kolejność wykonania nie jest gwarantowana, więc async pasuje do niezależnych skryptów, takich jak statystyki odwiedzin, a nie do kodu, który korzysta z innych plików. W zwykłych skryptach działa tylko razem z src.

HTML
<script src="/js/analytics.js" async></script>

type

brak | module | importmap | typ danych

Rodzaj zawartości. Pominięty oznacza zwykły JavaScript, więc pisanie type="text/javascript" jest zbędne. module tworzy moduł, importmap definiuje mapę importów dla modułów, a inne wartości, np. application/ld+json, zamieniają element w blok danych, którego przeglądarka nie wykonuje.

HTML
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Course",
  "name": "Kurs HTML i CSS od podstaw",
  "description": "24 lekcje z zadaniami i podglądem na żywo.",
  "provider": {
    "@type": "Organization",
    "name": "CodeWorlds"
  }
}
</script>

Takie dane strukturalne pomagają wyszukiwarkom zrozumieć, co znajduje się na stronie.

type="module"

moduł JavaScript

Uruchamia kod jako moduł: możesz w nim używać import i export, działa w trybie ścisłym, a jego zmienne nie trafiają do zakresu globalnego. Moduły domyślnie zachowują się jak skrypty z defer. Zwykle nie zadziałają po otwarciu pliku HTML prosto z dysku (file://), więc uruchamiaj stronę przez lokalny serwer.

HTML
<script type="module">
  import { formatPrice } from './utils.js';

  document.querySelector('#price').textContent = formatPrice(149);
</script>

nomodule

atrybut logiczny

Skrypt z tym atrybutem uruchomią tylko przeglądarki, które nie znają modułów. Służył do dostarczania wersji awaryjnej dla bardzo starych przeglądarek. Dziś moduły obsługuje każda popularna przeglądarka, więc rzadko go potrzebujesz.

HTML
<script type="module" src="/js/app.js"></script>
<script nomodule src="/js/app-legacy.js"></script>

integrity

skrót kryptograficzny, np. `sha384-…`

Subresource Integrity: przeglądarka sprawdza, czy pobrany plik ma dokładnie taki skrót, jaki podałeś. Jeśli plik został zmieniony, na przykład podmieniony na serwerze CDN, skrypt się nie wykona. Przy plikach z innej domeny wymagany jest też atrybut crossorigin.

HTML
<script
  src="/vendor/confetti.min.js"
  integrity="sha384-X3AWfWhQFwjzp273ynuHHCFyQuYlir97rA86ZO0Oogpfx0Mj78VDdnJqUkzHUU+e"
  defer
></script>

Skrót pliku wygenerujesz w terminalu poleceniem openssl dgst -sha384 -binary plik.js | openssl base64 -A. Wiele serwisów CDN podaje gotowy kod ze skrótem.

Więcej przykładów

#
Dane JSON w elemencie script
HTML
<script type="application/json" id="course">
  { "title": "Kurs Python", "lessons": 24 }
</script>
<p id="info">Wczytywanie…</p>

<script>
  const course = JSON.parse(document.getElementById('course').textContent);
  document.getElementById('info').textContent = course.title + ': ' + course.lessons + ' lekcje';
</script>
Podgląd

Pierwszy element ma typ application/json, więc przeglądarka go nie uruchamia. Drugi skrypt odczytuje z niego dane i wpisuje je do akapitu.

Domyślny CSS

#

Większość przeglądarek wyświetla ten element z takimi stylami domyślnymi:

CSS
script {
  display: none;
}

Obsługa przeglądarek

#

Szeroko dostępne

Działa we wszystkich nowoczesnych przeglądarkach, także na telefonach. Możesz używać bez obaw.

  • Chrome
  • Edge
  • Firefox
  • Safari

Dobre praktyki

#
  • Zawsze domykaj element: <script src="app.js"></script>. Zapis samozamykający się nie działa.
  • Skrypty w <head> oznaczaj defer albo type="module". Strona pokaże się szybciej, a kod na pewno znajdzie wszystkie elementy.
  • Nie umieszczaj w skryptach działających w przeglądarce haseł ani tajnych kluczy API. Każdy może je podejrzeć w źródle strony.

Powiązane hasła

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.