Завантаження документа DOMContentLoaded, load, beforeunload, unload

Процес завантаження HTML-документа, умовно, складається із трьох стадій:

  • DOMContentLoaded – браузер повністю завантажив HTML та побудував DOM-дерево.
  • load – браузер завантажив усі ресурси.
  • beforeunload/unload – відхід зі сторінки.

Усі ці стадії дуже важливі. На кожну можна повісити обробник, щоб зробити корисні дії:

  • DOMContentLoaded – означає, що всі DOM-елементи розмітки вже створені, можна їх шукати, вішати обробники, створювати інтерфейс, але при цьому можливо ще не довантажилися якісь картинки або стилі.
  • load – сторінка і всі ресурси завантажені, використовується рідко, зазвичай немає потреби чекати на цей момент.
  • beforeunload/unload – можна перевірити, чи зберіг відвідувач зміни, уточнити, чи дійсно він хоче залишити сторінку.

Далі ми розглянемо найважливіші деталі цих подій.

DOMContentLoaded

Подія DOMContentLoaded відбувається на document і підтримується у всіх браузерах, крім IE8-. Про підтримку подібного функціоналу на старих IE ми поговоримо наприкінці глави.

Обробник на нього вішається тільки через addEventListener:

У прикладі вище обробник DOMContentLoaded спрацює відразу після завантаження документа, не чекаючи на отримання картинки.

Тому на момент виведення alert і сама картинка буде невидна і її розміри - невідомі (крім випадку, коли картинка взята з кеша браузера).

У своїй суті, подія onDOMContentLoaded - проста, як пробка. Повністю створено DOM-дерево – і подія. Але з ним пов'язана низка істотних тонкощів.

DOMContentLoaded та скрипти

Якщо у документі є теги

Така поведінка прописана у стандарті.Його причина - скрипт може захотіти отримати інформацію зі сторінки, яка залежить від стилів, наприклад, ширину елемента, і тому має дочекатися завантаження style.css.

Побічний ефект – оскільки подія DOMContentLoaded буде чекати на виконання скрипту, то вона зачекає і завантаження стилів, які йдуть перед

window.onunload

Коли людина йде зі сторінки або закриває вікно, на window спрацьовує подію unload . У ньому можна зробити щось, що не вимагає очікування, наприклад закрити допоміжні popup-вікна, але скасувати сам перехід не можна.

Це дозволяє іншу подію - назавжди, що тому використовується набагато частіше.

window.onbeforeunload

Якщо відвідувач ініціював перехід на іншу сторінку або натиснув «зачинити вікно», то обробник напередпочатку може призупинити процес і запитати підтвердження.

Для цього йому потрібно повернути рядок. З історичних причин деякі браузери покажуть її, але більшість – це стандартне повідомлення.

Клікніть на кнопку в IFRAME нижче, щоб поставити обробник, а потім за посиланням, щоб побачити його в дії:

Емуляція DOMContentLoaded для IE8-

Перш ніж щось емулювати, зауважимо, що альтернативою події onDOMContentLoaded є виклик функції init зі скрипту в самому кінці BODY, коли основна частина DOM вже готова:

Причина, через яку зазвичай віддають перевагу саме подія – одна: зручність. Вішається обробник і не треба нічого писати в кінець BODY.

Міні-скрипт documentReady

Якщо ви все ж таки хочете використовувати onDOMContentLoaded крос-браузерно, то потрібно або підключити який-небудь фреймворк - майже всі надають такий функціонал, або використовувати функцію з міні-бібліотеки jquery.documentReady.js.

Незважаючина те, що в назві міститься слово jquery, ця бібліотечка не вимагає jQuery. Навпаки, вона є єдиною функцією під назвою $ , виклик якої $(callback) додає обробник callback на DOMContentLoaded (можна викликати багато разів), або, якщо документ вже завантажений - виконує його відразу.

Тут alert спрацює до завантаження картинки, але після створення DOM, зокрема після появи тексту. І так буде для всіх браузерів, у тому числі навіть дуже старі IE.

Технічно, емуляція DOMContentLoaded для старих IE здійснюється дуже кумедно.

Основний прийом – це спроба прокрутити документ викликом:

Метод doScroll працює тільки в IE і "методом тику" було виявлено, що він кидає виняток, якщо DOM не повністю створений.

Тому бібліотека намагається викликати прокручування, якщо не виходить – через setTimeout(. 1) намагається прокрутити його ще раз, і так доти, доки дія не перестане викликати помилку. На цьому етапі документ вважається завантаженим.

Усередині фреймів і в дуже старих браузерах такий підхід може помилятися, тому додатково ставиться резервний обробник на onload, щоб точно спрацював.

Найзатребуваніша подія з описаних - без сумніву, DOMContentLoaded. Багато сторінок зроблено так, що ініціалізують інтерфейси саме за цією подією.

Це зручно, адже можна написати скрипт, який буде запущений в момент, коли всі DOM-елементи доступні.

З іншого боку, слід мати на увазі, що подія DOMContentLoaded чекатиме не тільки, власне, на HTML-сторінку, а й зовнішні скрипти, підключені тегом

Коментарі

якщо більше 10 рядків — посилання на пісочницю (plnkr, JSBin, codepen…)

  • Якщо щось незрозуміло у статті, пишіть, що саме із якого місця.