Как сделать прелоадер для сайта и спиннер для кнопки?

Как сделать прелоадер для сайта и спиннер для кнопки?
Содержание:
  1. Назначение прелоадера
  2. Как создать прелоадер страницы
  3. Прелоадер на чистом CSS
  4. Прелоадер в виде анимированной svg иконки
  5. Прелоадер с использованием анимированной gif картинки
  6. Вариант прелоадера с использованием jQuery функции fadeOut
  7. Кнопка отправки со спиннером
  8. Комментарии

В этой статье разберём процесс создания прелоадера для сайта как на чистом CSS, так и с использованием изображений.

Назначение прелоадера

Страница любого сайта или веб-приложения не загружается мгновенно. На загрузку и отображение страницы необходимо некоторое время. При этом страница при её загрузке может видоизменяться. Обычно это происходит при загрузке стилей, шрифтов, картинок. Чтобы этот не привлекательный момент скрыть от пользователя, можно на время загрузки страницы отобразить пользователю какой-нибудь анимированный прелоадер. А после того, как страница полностью загрузится его убрать. Основная цель прелоадера — это улучшить впечатление пользователя о сайте.

Как создать прелоадер страницы

На самом деле создать прелоадер очень просто.

Для этого нужно сразу после открывающего тега body добавить код (HTML структуру прелоадера). С помощью CSS его необходимо настроить так, чтобы он занимал всю область viewport и находился над содержимым страницы. В качестве прелодера обычно используют анимированную картинку (svg, gif), или CSS-анимацию.

В процессе загрузки страницы её контент находится под прелодером. Пользователь видит только анимированную картинку.

После полной загрузки прелоадер необходимо скрыть. Чтобы это осуществить необходимо написать очень маленький скрипт. Это можно выполнить как на чистом JavaScript, так и с использованием библиотеки jQuery.

Прелоадер на чистом CSS

Этапы создания прелодера на чистом CSS:

1. Добавить после открывающего тега body следующий HTML-код:

HTML
<div class="preloader">
  <div class="preloader__row">
    <div class="preloader__item"></div>
    <div class="preloader__item"></div>
  </div>
</div>

Элемент .preloader – это контейнер, который будет занимать всю область просмотра и находится над содержимым страницы. .preloader__row и .preloader__item – необходимы для создания CSS-анимации, которую отобразим в центре viewport.

2. Создать следующие стили:

CSS
.preloader {
  /*фиксированное позиционирование*/
  position: fixed;
  /* координаты положения */
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  /* фоновый цвет элемента */
  background: #e0e0e0;
  /* размещаем блок над всеми элементами на странице (это значение должно быть больше, чем у любого другого позиционированного элемента на странице) */
  z-index: 1001;
}

.preloader__row {
  position: relative;
  top: 50%;
  left: 50%;
  width: 70px;
  height: 70px;
  margin-top: -35px;
  margin-left: -35px;
  text-align: center;
  animation: preloader-rotate 2s infinite linear;
}

.preloader__item {
  position: absolute;
  display: inline-block;
  top: 0;
  background-color: #337ab7;
  border-radius: 100%;
  width: 35px;
  height: 35px;
  animation: preloader-bounce 2s infinite ease-in-out;
}

.preloader__item:last-child {
  top: auto;
  bottom: 0;
  animation-delay: -1s;
}

@keyframes preloader-rotate {
  100% {
    transform: rotate(360deg);
  }
}

@keyframes preloader-bounce {

  0%,
  100% {
    transform: scale(0);
  }

  50% {
    transform: scale(1);
  }
}

.loaded_hiding .preloader {
  transition: 0.3s opacity;
  opacity: 0;
}

.loaded .preloader {
  display: none;
}

Размещение прелоадера над контентом осуществляется посредством задания ему фиксированного позиционирования и CSS-свойства z-index.

3. Вставить сценарий, который будет добавлять к элементу body класс loaded после полной загрузки страницы:

HTML
<script>
  window.onload = function () {
    document.body.classList.add('loaded');
  }
</script>

Этот скрипт очень резко скрывает прелоадер. Чтобы этот процесс улучшить, а именно выполнить это с анимацией можно использовать вместо вышеприведённого сценария этот:

HTML
<script>
  window.onload = function () {
    document.body.classList.add('loaded_hiding');
    window.setTimeout(function () {
      document.body.classList.add('loaded');
      document.body.classList.remove('loaded_hiding');
    }, 500);
  }
</script>
Демо прелоадера

Прелоадер в виде анимированной svg иконки

Процесс создания прелоадера в виде анимированной svg иконки не будет сильно отличаться от примера с использованием CSS-анимации.

1. Создадим HTML-разметку прелоадера и разместим её сразу же после открывающего тега body:

HTML
<div class="preloader">
  <svg class="preloader__image" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
    <path fill="currentColor"
      d="M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z">
    </path>
  </svg>
</div>

В качестве svg можно использовать любое другое изображение.

2. Добавим CSS:

CSS
.preloader {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  /* фоновый цвет */
  background: #e0e0e0;
  z-index: 1001;
}

.preloader__image {
  position: relative;
  top: 50%;
  left: 50%;
  width: 70px;
  height: 70px;
  margin-top: -35px;
  margin-left: -35px;
  text-align: center;
  animation: preloader-rotate 2s infinite linear;
}

@keyframes preloader-rotate {
  100% {
    transform: rotate(360deg);
  }
}

.loaded_hiding .preloader {
  transition: 0.3s opacity;
  opacity: 0;
}

.loaded .preloader {
  display: none;
}

3. Поместим на страницу следующий сценарий:

HTML
<script>
  window.onload = function () {
    document.body.classList.add('loaded_hiding');
    window.setTimeout(function () {
      document.body.classList.add('loaded');
      document.body.classList.remove('loaded_hiding');
    }, 500);
  }
</script>

Этот сценарий на чистом JavaScript. Но его можно написать с использованием библиотеки jQuery.

В этом случае он будет выглядеть следующим образом:

HTML
<script>
  $(window).on('load', function () {
    $('body').addClass('loaded_hiding');
    window.setTimeout(function () {
      $('body').addClass('loaded');
      $('body').removeClass('loaded_hiding');
    }, 500);
  }
</script>

Демо прелоадера

Пример прелоадера с градиентным фоном:

Демо прелоадера

Прелоадер с использованием анимированной gif картинки

В качестве изображения можно использовать не только svg, но и gif картинку.

HTML разметка:

HTML
<!-- Прелоадер -->
<div class="preloader">
  <div class="preloader__image"></div>
</div>

CSS для прелоадера:

CSS
.preloader {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  background: #fff;
  z-index: 1001;
}

.preloader__image {
  position: relative;
  top: 50%;
  left: 50%;
  width: 64px;
  height: 64px;
  margin-top: -32px;
  margin-left: -32px;
  background: url('preloader.gif') no-repeat 50% 50%; /*расположение (url) изображения gif и др. параметры*/
}

.loaded_hiding .preloader {
  transition: 0.3s opacity;
  opacity: 0;
}

.loaded .preloader {
  display: none;
}

Демо прелоадера

Небольшая коллекция анимированных gif-изображений имеется в этом архиве.

Вариант прелоадера с использованием jQuery функции fadeOut

Пример скрипта нв jQuery для скрытия прелоадере с использованием функции fadeOut:

JavaScript
$(window).on('load', function() {
  $('.preloader').fadeOut().end().delay(400).fadeOut('slow');
});

Демо прелоадера

Кнопка отправки со спиннером

Рассмотрим создание формы, работающей через AJAX. При её отправке будем переводить кнопку type="submit" в состояние disabled и показывать спиннер. Спиннер будем отображать до тех пор пока не прийдет ответ от сервера. Тем самым спиннер будет указывать что действие все ещё выполняется и оно не завершено.

1. Отправка формы с использованием XMLHttpRequest:

HTML
<style>
  @keyframes spinner-border {
    100% {
      transform: rotate(360deg);
    }
  }

  .submit-spinner {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    vertical-align: -0.125em;
    border: 0.2em solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    -webkit-animation: .75s linear infinite spinner-border;
    animation: .75s linear infinite spinner-border;
  }

  .submit-spinner_hide {
    display: none;
  }
</style>

<!-- Форма -->
<form action="#" method="post" id="user">
  ...
  <button type="submit"><span class="submit-spinner submit-spinner_hide"></span> Отправить</button>
</form>

<script>
  function sendForm() {
    const xhr = new XMLHttpRequest();
    xhr.open('POST', document.forms.user.action);
    xhr.responseType = 'json';
    xhr.onload = () => {
      document.forms.user.querySelector('[type="submit"]').disabled = false;
      document.forms.user.querySelector('.submit-spinner').classList.add('submit-spinner_hide');
      if (xhr.status !== 200) {
        return;
      }
      const response = xhr.response;
    }
    xhr.onerror = () => {
      document.forms.user.querySelector('[type="submit"]').disabled = false;
      document.forms.user.querySelector('.submit-spinner').classList.add('submit-spinner_hide');
    };
    document.forms.user.querySelector('[type="submit"]').disabled = true;
    document.forms.user.querySelector('.submit-spinner').classList.remove('submit-spinner_hide');
    xhr.send(new FormData(document.forms.user));
  }
  // при отправке формы
  document.forms.user.addEventListener('submit', (e) => {
    e.preventDefault();
    sendForm();
  });
</script>

2. Отправка формы с использованием Fetch:

JavaScript
async function sendForm() {
  try {
    document.forms.user.querySelector('[type="submit"]').disabled = true;
    document.forms.user.querySelector('.submit-spinner').classList.remove('submit-spinner_hide');
    let response = await fetch(document.forms.user.action, {
      method: 'post',
      body: new FormData(document.forms.user)
    });
    document.forms.user.querySelector('[type="submit"]').disabled = false;
    document.forms.user.querySelector('.submit-spinner').classList.add('submit-spinner_hide');
    if (response.ok) {
      let result = await response.json();
    }
  }
  catch (error) {
    document.forms.user.querySelector('[type="submit"]').disabled = false;
    document.forms.user.querySelector('.submit-spinner').classList.add('submit-spinner_hide');
    console.log(error);
  }
}
// при отправке формы
document.forms.user.addEventListener('submit', (e) => {
  e.preventDefault();
  sendForm();
});

Комментарии: 59

Дмитрий
Дмитрий

Здравствуйте, у меня на сайте для кнопок отправить и в корзину не срабатывает прелоадер https://i.imgur.com/4fSkhRk.png , можете подсказать, как сделать чтоб сработало? использовал код - 1. Отправка формы с использованием XMLHttpRequest:, id="user" у form обязательно надо установить?

Дмитрий
Дмитрий

У меня у форм везде стоит класс ajax он и отвечает за аякс запросы, может как то через него можно изменить код и получить данные? мне надо при успехе убирать класс .vise у кнопок

Александр Мальцев
Александр Мальцев

Добрый день! Не знаю как у вас реализовано, можно, например, добавить в ваш класс генерацию события. А потом отдельно его обрабатывать и удалять в нём нужный класс. Или добавить эту логику в класс. Вариантов реализации этой задачи можно придумать много. Делайте так как вам это удобнее.

Сергей Fortoo
Сергей Fortoo

Спасибо за отличную статью!!!

Заметил что прелоадер исчезает в момент перехода между страницами.

В принципе Вы уже отвечали на похожий вопрос

Вот Ваш ответ:
  1. Когда вы отправляете данные на сервер удаляете класс loaded:
document.body.classList.remove('loaded');

Только я сначала сам сделал похожий вариант, а потом увидел Ваш пример)

// добавил прелоадер по клику на любую ссылку
$(document).on('click', 'a', function(e){
    $('body').removeClass('loaded');
    $('body').removeClass('loaded_hiding');
});
// добавил прелоадер по клику на любую ссылку />

$(window).on('load', function () {
    $('body').removeClass('loaded'); // и здесь добавил
    $('body').addClass('loaded_hiding');
        
    window.setTimeout(function () {
      $('body').addClass('loaded');
      $('body').removeClass('loaded_hiding');
    }, 500);
});
И добавил прозрачности фону, так понятнее что страница не исчезла.
background: #e0e0e09e;

Теперь прелоадер крутится и когда отправляется запрос и когда загружается новая страница!

Александр Мальцев
Александр Мальцев

Пожалуйста! Рад, что она помогла.

Сергей Fortoo
Сергей Fortoo

Подумал, зачем ловить клик по ссылке, а почему-бы не ловить событие перезагрузки страницы?

вместо клика по ссылке
$(document).on('click', 'a', function(e){
событие
window.onbeforeunload = function() {
  $('body').removeClass('loaded');
  $('body').removeClass('loaded_hiding');
};
sibweb38
sibweb38
Здравствуйте!
Отличный прелоадер!
Подскажите пожалуйста – как сделать так что прелоадер работал и намобильном разрешении сайта? На мобильном разрешении его нет. На десктоп разрешении «Прелоадер в виде анимированной svg иконки» работает отлично.
ghost597
ghost597
Александр, приветствую! Могли бы показать пример реализации прелоадера для кнопки отправки формы? Чтобы к примеру на кнопке была надпись «Отправить», а после нажатия и до того момента как прийдет ответ от сервера вместо слова «Отправить» вращался какой-то спиннер? Чтобы было понятно что процесс идет, спасибо.
Александр Мальцев
Александр Мальцев
Привет! Добавил несколько примеров в статью.
Алексей
Алексей
Добрый день. Столкнулся с такой проблемой. Если переходить с внешнего адреса, например с поисковой системы, то сначала загружается часть сайта, а затем только включается прелоадер. Если переходить по внутренним ссылкам, работает отлично. Кэш очищал.
Алексей
Алексей
Проблема была в том, что вместо фона прелоадера я поставил довольно тяжелую картинку. В итоге на мгновенье появлялся незагруженный сайт. Проблему решил путем вставки картинки внутрь основного div прелоадера. То есть сначала загружается фон, а потом картинка.
Александр Мальцев
Александр Мальцев
Привет! Рад что получилось.
Алексей
Алексей
Благодарю Вас за такой полезный скрипт.
Вадим Туманов
Вадим Туманов
День добрый. подскажите пожалуйста есть ли решение у следующей задачи:
Нужен прелодер, который будеть ждать ответа от http сервиса, метод «post». пост возвращает ссылку на сайт, куда и должна перейти страница после получения ответа. просто обработка данных может идти очень долго.
ghost597
ghost597
Здравствуйте. Подскажите как быть в следующей ситуации: есть главная страница с формой, есть страница с результатом обработки данных, отправленных из формы. Установил ваш прелоадер, но он работает только непосредственно в момент открытия страницы, буквально за секунду до ее полной загрузки. Проблема в том, что на обработку данных из формы обычно требуется 5-6 секунд и все это время пользователь видит перед собой главную страницу, а хотелось бы весь этот момент загрузки скрыть прелоадером, который начнет показываться сразу после клика по сабмиту формы.
Александр Мальцев
Александр Мальцев
Привет!
Тут всё просто.
1. Когда вы отправляете данные на сервер удаляете класс loaded:
document.body.classList.remove('loaded');
2. Когда получаете ответ от сервера:
document.body.classList.add('loaded');
document.body.classList.remove('loaded_hiding');
Вот на примере кнопки: preloader-clean-css-3
ghost597
ghost597
Большое спасибо за понятный ответ! Я только совсем не силен в этой теме, можете подсказать что сделать чтобы прелоадер отрубался уже когда прийдет ответ от сервера, а не через 5 сек? Удаление значения 5000 не помогло:(
ghost597
ghost597
Еще раз спасибо, вроде понял как оно работает)
Наталья
Наталья
Добрый день, это очень простой прелодер. Он скрывается автоматически через 500ms и даже не проверяет загрузилась страничка или нет. Подскажите, пожалуйста, как мне можно проверить загрузились ли картинки в конкретном месте и только потом чтобы он скрылся?
Александр Мальцев
Александр Мальцев
Здравствуйте!
Скрытие прелоадера выполняется после полной загрузки страницы, для этого используется событие load:
window.onload = function () {
  //... 
}
При этом само скрытие прелоадера осуществляется плавно посредством CSS перехода:
transition: 0.3s opacity;
500ms — это время, через которое с момента начала перехода удаляется класс loaded_hiding и добавляется loaded. Оно нужно только для обеспечения плавности скрытия прелоадера. Вместо этого можно просто использовать transitionend, чтобы выполнить манипуляции с этими классами после окончания перехода.
window.onload = function () {
  const $body = document.body;
  const $preloader = $body.querySelector('.preloader');
  function afterTransition() {
    $body.classList.add('loaded');
    $body.classList.remove('loaded_hiding');
    $preloader.removeEventListener('transitionend', afterTransition);
  }
  $body.classList.add('loaded_hiding');
  $preloader.addEventListener('transitionend', afterTransition);
}
Пример с использованием transitionend: preloader-01
Надежда
Надежда
Здравствуйте! Помогите, пожалуйста!
Сделала так, чтобы скроллбар скрывался при загрузке прелоадера, воспользовавшись написанным в комментариях советом, но при появлении скроллбара сдвигается весь уже загруженный контент.
Какие-то безкостыльные способы решения этой проблемы быть могут?

margin-right: calc(-1 * (100vw — 100%)) уже пробовала. Этот способ мне не подходит, ибо контент вылезает за пределы экрана, а гугл-роботу не докажешь, что используется «overflow: hidden». Уже неделю не могу понять почему гугл-робот не хочет признать мой сайт оптимизированным для мобильных.
Александр Мальцев
Александр Мальцев
Здравствуйте! Попробуйте убрать прелоадер и проверьте без него. Может дело не в этом?
Ден
Ден
Отличная статья, доходчиво, просто…
Вопрос, как в последнем варианте (в анимации с тремя синими шарами) вставить вместо шаров изображение, чтоб оно также вращалось и крутилось? Интересно попробовать для практики.
itchief.ru/examples/lab.php?topic=javascript&file=preloader-with-jquery
Сухраб
Сухраб
Здравствуйте Александр. Вопрос такой. Мой прелоад находится в page1 и когда я нажимаю page2 и возвращаюсь к page1 анимация снова играеть. Что делать чтобы этот анимация играла только при запуске. Заранее спасибо
Александр Мальцев
Александр Мальцев
Здравствуйте! Не совсем ясно как у вас там это всё связано. Чтобы было понятно, сделайте готовый пример и предоставьте ссылку на него.
Игорь
Игорь
Здравствуйте!
Спасибо вам за информацию по установке прелоадера с gif. Всё работает по вашему коду чётко.
Хотел уточнить только один момент — перед загрузкой прелоадера (иногда!) у меня появляется контент (текст) шапки сайта. Буквально на долю секунды моргнёт. Браузер — гугл хром. Можно как то убрать кодом этот момент? Чтобы не появлялся контент перед прелоадером.
Игорь
Игорь
Вопрос решил переносом блока с кодом в шапку страницы. (делаю на тильде)
Александр Мальцев
Александр Мальцев
Привет! Отлично!
Игорь
Игорь
Александр, приветствую! А вы знаете как можно убрать scrollbar на время работы прелоадера (2сек)?
Александр Мальцев
Александр Мальцев
Привет! Это можно осуществить следующим образом:
1. Добавить в CSS следующее:
.hide-scroll-y {
  overflow-y: hidden;
}
2. Добавить класс hide-scroll-y к body:
...
<bode class="hide-scroll-y">
...
3. Удалить данный класс у body после загрузки страницы:
<script>
window.onload = function () {
  document.body.classList.add('loaded_hiding');
  window.setTimeout(function () {
    document.body.classList.add('loaded');
    document.body.classList.remove('loaded_hiding');
    // удаляем класс hide-scroll-y
    document.body.classList.remove('hide-scroll-y');
  }, 500);
}
</script>
Игорь
Игорь
Спасибо за ответ, Александр!

Буду вникать) Пока не выходит у меня. Надо изучать все это дело. Сохранил у себя ваш ответ. Вернусь к нему позже, как буду уже понимать что к чему
Александр Мальцев
Александр Мальцев
Да, тут, вроде всё просто. Если не получается, то можете сделать вашу страницу на «codepen.io», и оставить здесь ссылку.
Игорь
Игорь
Спасибо, Александр!

Я с кодом никогда не был знаком. Я делаю лендинг на Тильде. В основном все в конструкторе есть, можно и без кода обойтись. Но недавно распробовал CSS — вещь! А с JS уже сложнее все, тут уже темный лес — надо изучать)

Выбираю блок «Т123» для написания кода.

У меня 4 блока таких:
— В первом код для прелоадера
— Во втором стили (JQuery) разных элементов на сайте (отступы, размеры, формы и т.д.)
— В третьем ссылка для кнопки (записаться) для виджета Yclients
— В четвертом стили для полосы прокрутки.

Вот чтобы вставить этот код на скрытие скроллбара на время работы прелоадера. Мне надо в новом блоке все прописывать или вписать эти коды в первый блок с кодом прелоадера?

по 1 пункту я понимаю куда вставить стиль — ок
по 2 пункту тут уже сложно с троеточиями, куда его размещать я не понял
по 3 я понял — уже готовый скрипт
Александр Мальцев
Александр Мальцев
Конкретно по Тильде не подскажу, не использовал его.
Игорь
Игорь
Понял, спасибо!
Яна
Яна
Подскажите, пожалуйста, почему не получается увеличить время длительности прелоадера до 2 с. Использую ваш скрипт
$(window).on('load', function() {
$('.preloader').fadeOut().end().delay(2000).fadeOut('slow');
});
Александр Мальцев
Александр Мальцев
Сделайте через setTimeout:
$(window).on('load', function () {
  window.setTimeout(function () {
    $('.preloader').fadeOut().end().delay(400).fadeOut('slow');
  }, 2000);
});
Maks
Maks
Здравствуйте.
Вопрос такой, используя код gif, что именно надо вставить, чтобы был своя гифка? Я так понял в background надо вставить, но что именно? Ссылку на imgur моей гиф или что?
Александр Мальцев
Александр Мальцев
Здравствуйте! Нужно вставить путь к своей gif (вместо «preloader.gif»):
background: url('preloader.gif') no-repeat 50% 50%;
Евгений
Евгений
Добрый день! Как сделать длительность прелоадера побольше?
Александр Мальцев
Александр Мальцев
Здравствуйте! Для этого нужно просто указать вместо 500 любое другое количество миллисекунд. После этого функция, заданная в первом параметре setTimeout, будет запускаться уже не через 500, а другое количество миллисекунд после загрузки страницы.
Александр
Александр
Александр, добрый день.
А как сделать так, чтобы прелоадер скрывался при загрузке определенной части страницы.

Например, На странице используются гуглова рекаптча и АПИ Яндекс карт.
Иногда подкгрузка этих ресурсов и построение карт занимает время.
Можно-ли спрятать прелоадер когда загрузилось все, кроме например карт,
Александр Мальцев
Александр Мальцев
Привет! Такого события нет в JavaScript.
Можно, например, после того как HTML был полностью загружен и пройден парсером (не дожидаясь окончания загрузки CSS, изображений и т.д.):
document.addEventListener('DOMContentLoaded', function () {
  document.body.classList.add('loaded_hiding');
  window.setTimeout(function () {
    document.body.classList.add('loaded');
    document.body.classList.remove('loaded_hiding');
  }, 500);
});
Или на загрузку какого-то другого ресурса.
Александр
Александр
Понял. Спасибо. Буду экспериментировать
Uncle_Pasha
Uncle_Pasha
Кстати, теперь $(window).load deprecated на новых версиях jQuery, у меня возникла подобная проблема при подключении прелоадера по схеме из статьи. Полез на stackoverflow, и нашел решение:

заменить $(window).load на $(window).on('load', function(){...preloader...})

Вдруг кому-то пригодится :)
Александр Мальцев
Александр Мальцев
Спасибо! В статье для совместимости с jQuery 3.x этот момент изменил.
Александр
Александр
Александр спасибо! Отличное руководство. Скажите, как можно прикрутить прелоадер к mfilter2?
Александр Мальцев
Александр Мальцев
Для этого нужно внести изменения в файл "\assets\components\msearch2\js\web\default.js". Или лучше сделать его копию и подключить его в системных настройках. Это необходимо чтобы ваши изменения не были затёрты при переустановке компонента или его обновлении.
В этом файле необходимо найти следующее место:
beforeLoad: function () {
  $(this.options['wrapper']).addClass(this.options['loading_class']);
  this.results.css('opacity', 0);
  $(this.options.pagination_link).addClass(this.options.active_class);
  this.filters.find('input, select').prop('readonly', true).addClass(this.options.disabled_class);
},
afterLoad: function () {
  $(this.options['wrapper']).removeClass(this.options['loading_class']);
  this.results.css('opacity', 1);
  this.filters.find('.' + this.options.disabled_class).prop('readonly', false).removeClass(this.options.disabled_class);
},
В beforeLoad нужно добавить код для показа прелоадера, а в afterLoad — код для его скрытия.

Или можно даже с помощью CSS. Т.к. к элементу #mse2_mfilter добавляется класс loading когда идёт загрузка контента.
#before-load {
  display: none;
}
#mse2_mfilter.loading #before-load {
  display: block;
}
Но в этом случае блок #before-load нужно расположить в #mse2_mfilter.
Александр
Александр
Александр спасибо! Пытался реализовать это в js фильтра, но не выходит, если не трудно как в js прописать правильно?
Как я понимаю на этой строке
this.results.css('opacity', 0);
и
this.results.css('opacity', 1);
всё завязано?
Александр
Александр
Через css получилось, через Js не выходит.
Александр Мальцев
Александр Мальцев
В JavaScript тоже самое, только зачем, если с помощью CSS это можно решить.
Будет также:
beforeLoad: function () {
  $('#before-load').addClass('show'); // добавим класс show
  ...
},
afterLoad: function () {
  $('#before-load').removeClass('show'); // удалим класс show
  ...
}
Только изначально #before-load должен быть скрыт:
#before-load {
  ...
  display: none;
}
#before-load.show {
  display: block;
}
В коде да, реализовано через изменение уровня прозрачности элемента.
Александр
Александр
Александр, спасибо, Вам, за подробное решение. Не получается только сделать, чтобы этот блок с прелоадером был дочерним «position: relative». Не работает в этом случае, возможно я не много неправильно преподношу, но суть что я не могу использовать «position: relative» чтобы отцентрировать прелоадер в блоке результата mFilter2. Так всё работает.
Александр Мальцев
Александр Мальцев
В этом случае нужно добавить элемент-обёртку для элемента относительно которого необходимо позиционировать элемент.
Результат mFilter2 определяется с помощью элемента #mse2_results. Он расположен в чанке tpl.mFilter2.outer:
[[mFilter2?
  ...
  &tplOuter=`tpl.mFilter2.outer`
]]
В этом случае оборачиваем результат и помещаем в него элемент #before-load:
<div class="mse2_result_wrapper" style="position: relative;">
  <div id="before-load">...</div>
  <div id="mse2_results">
    [[+results]]
  </div>
</div>

[[mFilter2?
&tplOuter=`tpl.mFilter2.outer1`
]]
Александр
Александр
Александр Спасибо, всё максимально предельно понятно.
Аноним
Аноним
А как сделать чтобы загрузка работала только в определенном блоке

<div class="container">
<!-- В этом контейнере каталог товаров -->
</div>
Заранее спасибо
Аноним
Аноним
А можно сделать чтобы он назад всплывал, при нажатии на кнопку например?
Аноним
Аноним
Можно про 3й пункт поподробнее… куда его добавлять? ото прелоадер не скрывается
Александр Мальцев
Александр Мальцев
Вам необходимо на странице найти строчку, в которой подключается библиотека jQuery и после неё расположить этот скрипт.
<!-- Подключение библиотеки jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Располагаем после неё скрипт -->
<script>
$(window).load(function() {
  $('#before-load').find('i').fadeOut().end().delay(400).fadeOut('slow');
});
</script>
Аноним
Аноним
Благодарю за ответ!
Все работает!