W3docs

HTML-тег <script>

HTML-тег <script> встраивает или подключает JavaScript на страницу. Изучите src, async vs defer, type="module", размещение и атрибуты с примерами.

HTML-тег <script> объявляет клиентский скрипт — почти всегда JavaScript — в HTML-документе. Скрипты добавляют интерактивность: валидацию форм, динамическое обновление содержимого, работу с изображениями и реакцию на события пользователя. Тег может содержать скрипт встроенно (между открывающим и закрывающим тегами) или загружать внешний файл через атрибут src. Для более широкого обзора добавления скриптов на страницу см. HTML scripts.

Опасно

Если вы подключаете внешний файл со скриптами, не встраивайте скрипт в тот же тег <script>.

HTML-тег <script> можно размещать в элементе <head>, а также внутри элемента <body>. Скрипты, которые должны выполняться первыми, часто помещают в элемент <head> с атрибутом defer или в конце элемента <body>. Тег <script> можно использовать в HTML-документе несколько раз.

Тег script внутри HTML-документа, подключающий внешний JavaScript

Синтаксис

Тег <script> всегда идёт парами — открывающий <script> и закрывающий </script>. Встроенный код размещается между ними; для внешнего файла оставьте тег пустым и укажите в src путь к файлу:

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

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

Пример встроенного скрипта

Для выбора HTML-элемента JavaScript обычно использует метод 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>

Загрузка внешнего скрипта

В реальных проектах JavaScript почти всегда хранится в отдельном файле .js и загружается с помощью src. Это сохраняет HTML чистым, позволяет браузеру кешировать скрипт и использовать один файл на нескольких страницах:

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

Несколько важных замечаний:

  • Не смешивайте оба способа. Если присутствует src, любой код между тегами игнорируется. Используйте либо встроенный код, либо src, но не оба в одном теге.
  • type="text/javascript" не нужен. JavaScript является языком сценариев по умолчанию в современном HTML, поэтому type можно полностью опустить. Указывайте type только тогда, когда действительно нужен type="module" (см. ниже).
  • charset не влияет на внешние скрипты сегодня. Кодировка символов берётся из HTTP-заголовка Content-Type файла (и из кодировки самой страницы), поэтому атрибут charset у тега <script> устарел — не полагайтесь на него.

async vs. defer

По умолчанию, когда браузер встречает <script src="..."> при разборе HTML, он останавливает разбор, загружает скрипт, выполняет его и только затем продолжает. Это блокирует отрисовку. boolean-атрибуты async и defer решают эту проблему — оба загружают скрипт параллельно без блокировки разбора — но отличаются тем, когда скрипт выполняется:

АтрибутБлокирует разбор?Когда выполняетсяПорядок
(нет)ДаНемедленно при встречеВ порядке документа
deferНетПосле полного разбора HTML, непосредственно перед DOMContentLoadedВ порядке документа
asyncНетКак только завершается загрузкаКто первый загрузится (без порядка)
<!-- 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>

Используйте defer, когда скрипты зависят от DOM или друг от друга (наиболее распространённый случай). Используйте async для независимых скриптов, не зависящих от порядка выполнения, например счётчиков аналитики.

Информация

async и defer — это boolean-атрибуты: их простое наличие активирует их. Пишите их без значения (defer), а не в старом стиле XHTML defer="defer". То же относится к другим boolean-атрибутам, таким как disabled и checked. Оба атрибута игнорируются во встроенных скриптах (тех, у которых нет src).

Размещение скрипта: <head> или конец <body>

Место расположения <script> имеет значение, поскольку обычный скрипт блокирует разбор:

  • <head> с defer — современная рекомендация. Загрузка начинается рано, пока HTML ещё разбирается, а выполнение ожидает готовности DOM. Вы получаете быструю загрузку без блокировки.
  • Конец <body> — классический подход. К тому моменту, когда парсер доходит до скрипта, весь DOM уже существует, поэтому скрипт может безопасно обращаться к элементам. Никакие атрибуты не нужны.
<head>
  <script src="app.js" defer></script>
</head>
<body>
  <!-- page content -->
</body>

Избегайте обычного <script src> (без async/defer) в <head>, так как это блокирует отрисовку страницы до тех пор, пока скрипт не будет загружен и выполнен.

ES-модули с type="module"

Установка type="module" превращает скрипт в ES-модуль. Модульные скрипты отличаются от классических:

  • Они поддерживают import / export, что позволяет разделять код по файлам.
  • Они отложены по умолчанию — модульные скрипты всегда ждут завершения разбора HTML (атрибут defer не нужен).
  • Они всегда выполняются в строгом режиме и имеют собственную область видимости верхнего уровня (переменные не утекают в глобальный объект).
<script type="module" src="main.js"></script>

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

Для поддержки очень старых браузеров, не понимающих модули, можно дополнить модуль запасным скриптом с nomodule — современные браузеры выполняют модуль и игнорируют запасной, старые — наоборот.

Замечание об XHTML и устаревшей разметке

В современном HTML атрибут type не нужен, и содержимое встроенного скрипта не нужно оборачивать в секцию CDATA. Обёртка //<![CDATA[ ... //]]> была нужна только в XHTML, где содержимое скрипта разбиралось как разметка и специальные символы вроде < и & нужно было экранировать или защищать. Если вы пишете стандартный HTML, это можно игнорировать.

Атрибуты

АтрибутЗначениеОписание
srcURLURL внешнего файла скрипта (относительный или абсолютный).
async(boolean)Внешний скрипт загружается параллельно и выполняется сразу после загрузки, не блокируя разбор.
defer(boolean)Внешний скрипт загружается параллельно и выполняется по порядку после разбора HTML.
typeтип медиаОбычно опускается (JavaScript используется по умолчанию). Установите module для загрузки ES-модуля.
charsetкодировкаУстарел — не имеет эффекта; кодировка берётся из HTTP-заголовка Content-Type файла.
crossoriginanonymous | use-credentialsНастраивает CORS для запроса внешнего скрипта.
integrityхешХеш Subresource Integrity для проверки загруженного скрипта.

Тег <script> поддерживает глобальные атрибуты и атрибуты событий.

Практика

Практика
Какой атрибут позволяет внешнему скрипту загружаться без блокировки разбора и выполняться по порядку после разбора HTML?
Какой атрибут позволяет внешнему скрипту загружаться без блокировки разбора и выполняться по порядку после разбора HTML?
Was this page helpful?