В данной статье мы рассмотрим, как показать информацию о процессе загрузки сайта до самой загрузки каких-либо скриптов и полного 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 дерево по каким-то причинам будет очень долго строиться и отображаться. Что-бы показать хоть какой-то процесс или возможно наличие обрыва соединения.
Упаковка в plugin WordPress
Для удобства управления, все вышеописанное можно упаковать в плагин WP. Например такой код позволит подключить стилевой и скриптовый файлы:
<?php
/*
Plugin Name: Easy Page Preloader
Plugin URI: http://consultapp.ru/pre-loader-for-site/
Description: Adding a preloader to the pages. No conflicts with SEO. You can set your own logo.
Version: 1.0
Author: Dmitry Egorov
Author URI: http://consultapp.ru/
License: GPLv2
*/
//********************************************************************
//*************************** PLUGIN CORE ****************************
//********************************************************************
function ca_epl(){
wp_enqueue_style( 'html-loader', plugins_url( '/style.css', __FILE__ ) );
wp_enqueue_script( 'html-loader-script', plugins_url( '/script.js', __FILE__ ), array(), '1.0.1', true );
}
add_action('wp_enqueue_scripts', 'ca_epl');
Заключение
В статье мы рассмотрели, как с помощью прсевдоэлемента ::before добавленного к тегу <html> добавить preloader на страницу, и отключать его по событию load на объекте window.