Pre-loader для сайта
В данной статье мы рассмотрим, как показать информацию о процессе загрузки сайта до самой загрузки каких-либо скриптов и полного HTML документа.
Наша задача каким-то образом показать элемент на странице, до загрузки чего бы то ни было тяжелого вроде скриптов, как минимум полной загрузки <body>, а потом отследить загрузку и убрать этот элемент. На первый взгляд это кажется противоречащим самому себе. Как показать что-то, до загрузки части документа, который как раз и содержит визуальную информацию и убрать после?
Однако есть один момент. Теги <html>, <head> читаются раньше, плюс в CSS есть псевдоэлементы, нас интересует ::before.
Псевдоэлементы ::before, ::after — это часть селекторов CSS, которые используют для вставки содержимого, которого нет в исходном коде.
Решение
- Добавляем стилизованный псевдоэлемент ::before на тег <html> с нужным нам элементом-прелоадером;
- Отлавливаем в JS момент загрузки страницы (2 варианта). Убираем отображение загрузки, с помощью добавления класса конца загрузки тегу <html>.
Подробное описание
Рассмотрим пример добавление прелоадера на примере нашего сайта.
Добавляем в <head>, напрямую или через файл, стили:
html::before {
background-size: 150px !important;
opacity: 1;
content: "";
display: block;
position: fixed;
z-index: 999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url("/logo-animate.svg") no-repeat center, #fff;
transition: opacity 0.3s ease-in;
}
html.loaded::before {
opacity: 0;
pointer-events: none;
}
Здесь видно, что в нашем случае content — пустая строка. Мы позиционируем по центру background с SVG лоадером, растягивая слой на весь экран, а так же выставляя большой z-index, что позволит нам скрывать постепенную загрузку/отображение элементов. Плюс небольшая анимация перехода.
Далее у нас есть 2 варианта работы с JS, мы можем поймать события:
- DOMContentLoaded – браузер полностью загрузил HTML, было построено DOM-дерево, но внешние ресурсы, такие как картинки
<img>
и стили, могут быть ещё не загружены; load
– браузер загрузил HTML и внешние ресурсы (картинки, стили и т.д.).
Выбор за Вами, понятно, что первое событие будет раньше и Вы можете даже добавить дополнительный этап загрузки, между DOMContentLoaded и load соответственно. Мы же остановимся на load:
window.addEventListener("load", () => {
document.documentElement.classList.add("loaded");
});
setTimeout(()=>{
if(!document.documentElement.classList.contains("loaded"))
document.documentElement.classList.add("loaded");
}, 10000);
Объекту window добавляем событие load, по которому добавляем класс окончания загрузки на тег <html> (в JS к нему можно обращаться как к documentElement).
Так же, для очень медленных соединений, мы посчитали необходимым снимать loader (setTimeout) через 10 сек, после загрузки скрипта, если DOM дерево по каким-то причинам будет очень долго строиться и отображаться. Что-бы показать хоть какой-то процесс или возможно наличие обрыва соединения.
Заключение
В статье мы рассмотрели, как с помощью прсевдоэлемента ::before добавленного к тегу <html> добавить preloader на страницу, и отключать его по событию load на объекте window.