Выбрать главу

Во время этой стадии не происходит ничего интересного. Запрос на загрузку страницы уже был сделан, но еще ничего не загружено.

Стадия вторая

Здесь уже более насыщенный процесс, во время которого происходят загрузка и обработка сырой разметки, а также DOM-страницы.

Здесь стоит отметить, что внешние ресурсы вроде изображений и связанных с ними таблиц стилей еще не считаны. Вы видите только сырое содержимое, определенное разметкой страницы или документа.

Стадия третья

Во время заключительной стадии страница уже полностью загружена со всеми изображениями, таблицами стилей, сценариями и прочими внешними ресурсами, преобразованными в то, что вы видите:

На этой стадии индикаторы загрузки браузера прекращают анимацию, и именно здесь вы почти всегда оказываетесь при взаимодействии с HTML-документом. Учитывая все сказанное, иногда страница может оказаться в промежуточном состоянии, когда 99 % контента загрузилось, но какой-то случайный элемент застревает в загрузке навечно. Если вы посещали один из вирусных, или информационных, или фид-сайтов, то прекрасно поймете, о чем я.

Теперь, когда у вас есть представление о трех стадиях, которые проходит документ при загрузке содержимого, перейдем к более интересной части. А к трем стадиям мы вернемся в ближайших разделах.

DOMContentLoaded и load Events

Есть два события, представляющих два основных ориентира в процессе загрузки страницы: DOMContentLoaded и load. DOMContentLoad срабатывает в конце стадии 2, когда DOM страницы полностью обработан. Событие load срабатывает в конце стадии 3, как только страница полностью завершает загрузку. Вы можете использовать эти события для выбора времени выполнения кода.

Ниже приведен фрагмент кода с использованием этих двух событий:

document.addEventListener("DOMContentLoaded", theDomHasLoaded,

false);

window.addEventListener("load", pageFullyLoaded, false);

function theDomHasLoaded(e) {

// делает что-нибудь

}

function pageFullyLoaded(e) {

// снова делает что-нибудь

}

Вы используете эти события так же, как и любые другие, но при этом важно учесть, что вам надо прослушивать DOMContentLoaded из элемента document, а load — из элемента window.

Теперь, когда со всеми скучными техническими деталями покончено, подумаем, почему эти события важны? Очень просто. Если у вас есть код, опирающийся на работу с DOM вроде всего того, что использует querySelector или querySelectorAll, то вам нужно обеспечить, чтобы этот код запускался только после полной загрузки DOM. Если вы попробуете обратиться к DOM до этого момента, то либо получите неполные результаты, либо не получите их вообще.

Вот прекрасный радикальный пример от Кайла Мюррея:

<!DOCTYPE html>

<html>

<head>

<script>

// попытайтесь проанализировать здесь содержимое книги

</script>

</head>

<body>

[Вставьте здесь полную копию /Войны и мира/]

</body>

</html>

Верный способ избежать ситуации, в которой код запускается до момента готовности DOM, — это прослушать событие DOMContentLoaded и установить запуск кода, опирающегося на DOM только тогда, когда это событие будет услышано:

document.addEventListener("DOMContentLoaded", theDomHasLoaded, false);

function theDomHasLoaded(e) {

let headings = document.querySelectorAll("h2");

// делает что-нибудь с изображениями

}

Для случаев, когда нужно, чтобы код запускался только после полной загрузки страницы, используйте событие load. За все годы использования JavaScript мне не так часто приходилось использовать это событие на уровне документа, за исключением проверки итоговых размеров загруженного изображения или создания простых индикаторов прогресса.

Сценарии и их расположение в DOM

В главе 8 мы рассмотрели различные способы для определения положения сценариев внутри документа. Вы видели, что положение элементов в DOM влияет на момент запуска. В этом разделе подтвердим эту простую истину и немного углубимся.

Вспомним, что простой элемент сценария может быть встроенным кодом в какой-то части документа:

<script>

let number = Math.random() * 100;

console.log("A random number is: " + number);

</script>

Он также может быть чем-то, что ссылается на некий код во внешнем файле:

<script src="/foo/something.js"></script>

А теперь важная деталь относительно этих элементов. Ваш браузер считывает DOM последовательно сверху вниз. Любые элементы сценария, встречающиеся на его пути, будут считаны в том порядке, в каком они расположены в DOM.