Событие onDOMContentLoaded срабатывает при загрузке документа, после выполнения всех тегов SCRIPT.
В отличие от window.onload, оно не ждёт загрузки дополнительных ресурсов, поэтому наступает гораздо раньше.
На момент наступления onDOMContentLoaded, дерево DOM полностью построено и все элементы доступны. Поэтому это событие часто используют для инициализации интерфейса. Во фреймворках для него отводят специальные функции: $(ready), Ext.onReady и т.п.
Но, как мы увидим, у него есть ряд важных особенностей, которые делают такое применение не лучшим выбором.
Событие DOMContentLoaded поддерживается во всех браузерах, кроме IE<9. Про поддержку аналогичного функционала в старых IE мы поговорим дальше.
Обработчик на него вешается так:
document.addEventListener( "DOMContentLoaded", ready, false );
Пример (в ифрейме):
<script>
function yelp() {
alert('DOM готов (а iframe - нет)');
}
*!*
document.addEventListener( "DOMContentLoaded", yelp, false );
*/!*
</script>
<iframe src="http://example.com" height="80"></iframe>
Тонкости DOMContentLoaded
В своей сути, событие onDOMContentLoaded — простое, как пробка. Полностью создано DOM-дерево — и вот событие.
Но с ним связан ряд существенных тонкостей.
DOMContentLoaded и скрипты
Если в документе есть теги SCRIPT, то браузер обязан их выполнить до того, как построит DOM. Поэтому событие DOMContentLoaded ждёт загрузки и выполнения таких скриптов.
DOMContentLoaded не ждёт скриптов с атрибутами async/defer, при условии поддержки атрибута браузером, а также скриптов, добавленных через DOM.
Браузер Opera — особый. Он ждёт любые скрипты. Это не по стандарту, но увы..
- Побочный эффект: если на странице подключается скрипт с внешнего ресурса (реклама), и он тормозит, то инициализация интерфейсов по
DOMContentLoadedможет сильно задержаться.
DOMContentLoaded и стили
Внешние стили никак не влияют на событие DOMContentLoaded. Но есть один нюанс. Если после стиля идёт скрипт, то этот скрипт обязан дождаться, пока стиль загрузится:
<link type="text/css" rel="stylesheet" href="style.css"> <script> // сработает после загрузки style.css </script>
Такое поведение прописано в стандарте. Его причина — скрипт может захотеть получить информацию со страницы, зависящую от стилей, например, ширину элемента.
В результате событие DOMContentLoaded будет также ждать стилей.
Браузер Opera — особый. В нём скрипты не ждут стилей. Это поведение не соответствует стандарту.
Автозаполнение
Firefox/Chrome автозаполняют формы по DOMContentLoaded.
Это означает, что если на странице есть форма для ввода логина-пароля, то браузер введёт в неё запомненные значения только по DOMContentLoaded.
- Побочный эффект: если
DOMContentLoadedожидает множества скриптов и стилей, то посетитель не сможет воспользоваться автозаполненными значениями до полной их загрузки.
Чтобы всё было хорошо, событие DOMContentLoaded должно просходить как можно раньше.
Этого можно достичь, используя defer/async/добавление через DOM.
IE до 9
Реализация кросс-браузерного аналога onDOMContentLoaded описана в статье Кроссбраузерное событие onDOMContentLoaded.
Альтернативой событию является вызов функции init из скрипта в самом конце BODY, когда основная часть DOM уже готова:
<body> ... <script> init(); </script> </body>
Это вполне кросс-браузерно. Единственная проблема — нельзя document.body.appendChild вызывать из такой функции в IE6.
Причина, по которуй обычно предпочитают именно событие — удобство. Вешается обработчик и не надо ничего писать в конец BODY.
Комментарии
- Приветствуются комментарии, содержащие дополнения и вопросы по статье, и ответы на них.
- Если ваш комментарий касается задачи -- откройте её в отдельном окне и напишите там.
- Комментарии без смысла, с рекламой или не о статье вообще - удаляются.