- События при загрузке HTML-документа
- readyState
- Window: DOMContentLoaded event
- Syntax
- Document: DOMContentLoaded event
- Примеры
- Основное применение
- Отложенный DOMContentLoaded
- Проверка того, завершена ли загрузка
- Живые примеры
- HTML
- JS
- Result
- Спецификации
- Браузерная совместимость
- Смотрите также
- Found a content problem with this page?
- MDN
- Support
- Our communities
- Developers
События при загрузке HTML-документа
И добавим обработчик для DOMContentLoaded. Это можно сделать только через метод addEventListener объекта document:
document.addEventListener("DOMContentLoaded", ready); function ready(event) { console.log("DOMContentLoaded"); console.log(`Изображение: ${image.offsetWidth}x${image.offsetHeight}`); }
В обработчике мы выводим размер изображения. Обновляем документ и видим, что размер нулевой. Это как раз и говорит о том, что событие DOMContentLoaded возникает до загрузки ресурсов (если, конечно, они не были закэшированы). В целом, все понятно и просто. Но, как всегда, есть один нюанс. Данное событие отрабатывает только после выполнения всех скриптов, записанных в HTML-документе. Например, если мы добавим вот такой скрипт в конец документа:
script> console.log("вызов метода write"); document.write('Добавляем тег p на страницу'); script>
- Скрипты с атрибутом async (который мы рассмотрим немного позже), не блокируют DOMContentLoaded.
- Скрипты, сгенерированные динамически при помощи document.createElement(‘script’) и затем добавленные на страницу, также не блокируют это событие.
script> // скрипт не выполняется, пока не загрузятся стили console.log(getComputedStyle(document.body).marginTop); script>
То браузер будет вынужден сгенерировать событие DOMContentLoaded после загрузки стилей. Вот эти нюансы следует иметь в виду при работе с этим событием. Следующее событие load для объекта window работает очень просто: оно генерируется браузером, когда HTML-документ полностью загружен вместе со всеми связанными с ним ресурсами:
window.onload = function(event) { console.log("load"); console.log(`Изображение: ${image.offsetWidth}x${image.offsetHeight}`); }
Здесь при обновлении документа мы увидим полные размеры изображения. Следующее событие unload объекта window выполняется когда пользователь практически покинул HTML-страницу. Обычно, в этот момент отправляется статистика поведения пользователя на странице серверу:
window.addEventListener("unload", function() { console.log("отправка данных на сервер"); });
Если мы теперь станем обновлять станицу, то в консоли будет появляться данное сообщение. К сожалению, продемонстрировать работу этого события как то приятнее не получается. Поэтому, далее, пара слов теории. Для отправки данных серверу в объекте navigator существует такой специальный метод: navigator.sendBeacon(url, data); Здесь url – это путь к скрипту на сервере, который будет принимать данные data. Особенность этого метода в том, что при закрытии страницы нет необходимости дожидаться окончания его работы. Браузер будет его выполнять в фоне даже при отсутствии ранее открытого документа. Поэтому, если вы хотите что-то отправить на сервер при закрытии HTML-страницы, то это лучше всего делать через этот метод. На практике он реализуется примерно так:
window.addEventListener("unload", function() { navigator.sendBeacon("/analytics.php", JSON.stringify(myData)); };
window.onbeforeunload = function() { return false; };
Теперь, при обновлении документа будет появляться окно, спрашивающее пользователя: действительно ли он хочет перезагрузить страницу. Это должно привлечь его внимание и напомнить о возможных последствиях такого действия, например, на несохранение каких-то данных. Ранее, в браузерах можно было писать свои сообщения в таких окнах, примерно так:
window.onbeforeunload = function() { return "Не уходи не попрощавшись!"; };
В этом случае также будет появляться окно с предупреждением, но к с частью строка сообщения в новых браузерах игнорируется и заменяется стандартным предупреждением, так как программисты прошлого злоупотребляли этой возможностью.
readyState
- «loading» – документ в процессе загрузки;
- «interactive» – документ был полностью прочитан (парсинг документа завершен);
- «complete» – документ был полностью прочитан и все ресурсы (изображения, стили и т.п.) тоже загружены.
removeImage(); function removeImage() { if(document.readyState == "loading") { console.log("документ грузится, вешаем обработчик"); document.addEventListener("DOMContentLoaded", removeImage); } else { console.log("удаляем изображение"); document.body.remove(image); } }
По аналогии могут быть обработаны и остальные свойства. Для полноты картины пару слов о событии readystatechange, которое появилось до событий DOMContentLoaded, load, unload, beforeunload и в старых версиях JavaScript процесс загрузки документа контролировался через него. Например, так:
document.addEventListener('readystatechange', function() { console.log(document.readyState); });
Теперь при обновлении страницы мы можем увидеть изменение состояний свойства document.readyState в процессе загрузки. Однако такой механизм отслеживания ушел в прошлое и сейчас уже нет смысла о нем подробно говорить. Итак, на этом занятии мы с вами рассмотрели события DOMContentLoaded, load, unload, beforeunload и поговорили о свойстве document.readyState которое дополняет работу с этими событиями.
Window: DOMContentLoaded event
The DOMContentLoaded event fires when the HTML document has been completely parsed, and all deferred scripts ( and ) have downloaded and executed. It doesn’t wait for other things like images, subframes, and async scripts to finish loading.
DOMContentLoaded does not wait for stylesheets to load, however deferred scripts do wait for stylesheets, and the DOMContentLoaded event is queued after deferred scripts. Also, scripts which aren’t deferred or async (e.g. ) will wait for already-parsed stylesheets to load.
The original target for this event is the Document that has loaded. You can listen for this event on the Window interface to handle it in the capture or bubbling phases. For full details on this event please see the page on the Document: DOMContentLoaded event.
A different event, load , should be used only to detect a fully-loaded page. It is a common mistake to use load where DOMContentLoaded would be more appropriate.
This event is not cancelable.
Syntax
Use the event name in methods like addEventListener() , or set an event handler property.
addEventListener("DOMContentLoaded", (event) => >); onDOMContentLoaded = (event) => >;
Document: DOMContentLoaded event
Событие DOMContentLoaded запускается когда первоначальный HTML документ будет полностью загружен и разобран, без ожидания полной загрузки таблиц стилей, изображений и фреймов.
Всплытие | да |
---|---|
Отменяемый | Да (хотя указано как простое событие, которое не может быть отменено) |
Интерфейс | Event |
Свойство обработчика событий | нет |
Разные события, load , должны быть использованы только для обнаружения полностью загруженной страницы. Это распространённая ошибка в использовании load , там где DOMContentLoaded было бы более уместным.
Синхронный JavaScript останавливает разбор DOM. Если вы хотите что бы DOM был разобран как можно быстрее после того как пользователь запросит страницу, вы должны сделать ваш JavaScript асинхронным and оптимизировать загрузку таблиц стилей. Если загружать как обычно, таблицы стилей тормозят разбор DOM так как они загружаются параллельно, «крадя» трафик у основного HTML документа.
Примеры
Основное применение
.addEventListener('DOMContentLoaded', (event) => console.log('DOM полностью загружен и разобран'); >);
Отложенный DOMContentLoaded
script> document.addEventListener('DOMContentLoaded', (event) => console.log('DOM полностью загружен и разобран'); >); for( let i = 0; i 1000000000; i++) > // Этот синхронный скрипт откладывает разбор DOM, // так что событие DOMContentLoaded будет запущено позже. script>
Проверка того, завершена ли загрузка
DOMContentLoaded может сработать до того, как ваш скрипт будет запущен, поэтому разумно это проверить, перед добавлением обработчика.
function doSomething() console.info('DOM загружен'); > if (document.readyState === 'loading') // Загрузка ещё не закончилась document.addEventListener('DOMContentLoaded', doSomething); > else // `DOMContentLoaded` Уже сработал doSomething(); >
Живые примеры
HTML
div class="controls"> button id="reload" type="button">Reloadbutton> div> div class="event-log"> label>Event log:label> textarea readonly class="event-log-contents" rows="8" cols="30">textarea> div>
body display: grid; grid-template-areas: "control log"; > .controls grid-area: control; display: flex; align-items: center; justify-content: center; > .event-log grid-area: log; > .event-log-contents resize: none; > label, button display: block; > #reload height: 2rem; >
JS
const log = document.querySelector('.event-log-contents'); const reload = document.querySelector('#reload'); reload.addEventListener('click', () => log.textContent =''; window.setTimeout(() => window.location.reload(true); >, 200); >); window.addEventListener('load', (event) => log.textContent = log.textContent + 'load\n'; >); document.addEventListener('readystatechange', (event) => log.textContent = log.textContent + `readystate: $document.readyState>\n`; >); document.addEventListener('DOMContentLoaded', (event) => log.textContent = log.textContent + `DOMContentLoaded\n`; >);
Result
Спецификации
Браузерная совместимость
BCD tables only load in the browser
Смотрите также
Found a content problem with this page?
This page was last modified on 17 июл. 2023 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
Our communities
Developers
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.