Модификации модального окна



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

Рассмотрим вариант вызова модального окна через какое-то время.

Тот код для открытия модального окна, что у нас уже есть:

Код
modalTrigger.forEach(btn => {

  // Открытие модального окна

  btn.addEventListener('click', () => {

  modal.classList.add('show');
  modal.classList.remove('hide');

  // запрещаем скролл страницы

  document.body.style.overflow = 'hidden';
  });
});

мы вынесем в отдельную функцию, которую и будем использовать:

Код
function openModal() {
  modal.classList.add('show');
  modal.classList.remove('hide');
  // запрещаем скролл страницы
  document.body.style.overflow = 'hidden';
}

modalTrigger.forEach(btn => {
  // Открытие модального окна
  btn.addEventListener('click', openModal);
});

В самом низу кода мы будем устанавливать интервал времени, через который на сайте должно появляться модальное окно, например, через 5 секунд:

Код
// Появление модального окна через интервал времени

const modalTimerId = setTimeout(openModal, 5000);

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

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

Код
// Функция открытия модального окна

function openModal() {

  modal.classList.add('show');
  modal.classList.remove('hide');

  // запрещаем скролл страницы

  document.body.style.overflow = 'hidden';

  // обнуляем таймер

  clearInterval(modalTimerId);
};

Функционал открытия модального окна при долистывании страницы до конца

Мы можем использовать событие scroll для того, чтобы отслеживать действия пользователя. Событие отслеживается для глобального объекта window.

Код
window.addEventListener('scroll', () => {
   
});

Нам нужно отследить момент, когда пользователь пролистает страницу сайта до самого конца.

Можно воспользоваться свойством pageYOffset, которое отслеживает сколько пикселей сверху по оси Y отлистал пользователь.

Также у нас есть свойство scrollHeight, которое показывает полную высоту элемента с учетом прокрутки, которая была сверху.

Можно написать формулу, в которой будем сравнивать сумму прокрученной части и видимой с полной высотой элемента, и если они равны, значит пользователь пролистал страницу до конца.

Код
window.addEventListener('scroll', () => {
  if (window.pageYOffset + document.documentElement.clientHeight >= document.documentElement.scrollHeight) {
   
  }
});

В некоторых браузерах такая конструкция некорректно отрабатывает (не открывается модальное окно при пролистывании страницы до конца) и поэтому добавляем -1

Код
window.addEventListener('scroll', () => {
  if (window.pageYOffset + document.documentElement.clientHeight >= document.documentElement.scrollHeight -1) {
   
  }
});

Внутри функции помещаем вызов функции openModal(), пользователь долистал страницу до конца - вызываем открытие модального окна:

Код
window.addEventListener('scroll', () => {
  if (window.pageYOffset + document.documentElement.clientHeight >= document.documentElement.scrollHeight -1) {
  openModal();
  }
});

Но в данном скрипте есть один недочет: нам нужно, чтобы при пролистывании страницы до конца модальное окно появилось только один раз, сейчас же, если долистать до конца, потом отмотать немнoго вверх и опять опуститься до конца, оно опять откроется.

Пофиксить данное поведение можно с помощью дополнительного параметра для обработчика событий once: true:

Код
window.addEventListener('scroll', () => {
  if (window.pageYOffset + document.documentElement.clientHeight >= document.documentElement.scrollHeight -1) {
  openModal();
  }
}, {once: true});

Но в данном случае такое решение нам не подходит, поскольку долистав до конца страницу сайта, мы ничего не увидим, так как при малейшем скролле страницы событие исчезает.

Другим вариантом будет удаление обработчика события, когда он выполнился (через removeEventListener())

Создадим функцию showModalByScroll() и поместим в неё функционал из обработчика события, а в самом обработчике оставляем только ссылку на эту функцию

Код
function showModalByScroll() {
  if (window.pageYOffset + document.documentElement.clientHeight >= document.documentElement.scrollHeight -1) {
  openModal();
  }
};

window.addEventListener('scroll', showModalByScroll);

Далее в функции showModalByScroll(), после того, как сработала функция открытия модального окна, удаляем обработчик события, указывая какое событие и какая функция были заданы:

Код
function showModalByScroll() {
  if (window.pageYOffset + document.documentElement.clientHeight >= document.documentElement.scrollHeight -1) {
  openModal();
  window.removeEventListener('scroll', showModalByScroll);
  }
};

window.addEventListener('scroll', showModalByScroll);

Всего комментариев: 0

Имя *:
Email *:
Код *:
Хостинг от uCoz