Содержание
  1. Содержание
  2. Зачем нужны pop-up
  3. Типы pop-up по триггеру
  4. Базовый код модального окна
  5. Pop-up по таймеру
  6. Pop-up по скроллу
  7. Pop-up при попытке уйти
  8. Слайдер снизу/сбоку
  9. Отправка данных формы
  10. Ограничение частоты показа
  11. Как не раздражать посетителей
  12. Отслеживание в аналитике
  13. FAQ
  14. Заключение

Pop-up окно с предложением скидки, чек-листа или просто формой обратной связи может удвоить конверсию лендинга. Многие готовые сервисы вроде Popup Maker или OptinMonster стоят $20-50 в месяц и требуют интеграции через скрипт. На самом деле сделать рабочий, красивый pop-up можно на чистом HTML, CSS и JavaScript за полчаса. В статье — полный код для нескольких типов попапов, триггеры (по таймеру, по скроллу, по уходу), и базовая аналитика.

Содержание

  1. Зачем нужны pop-up
  2. Типы pop-up по триггеру
  3. Базовый код модального окна
  4. Pop-up по таймеру
  5. Pop-up по скроллу
  6. Pop-up при попытке уйти
  7. Слайдер снизу/сбоку
  8. Отправка данных формы
  9. Ограничение частоты показа
  10. Как не раздражать посетителей
  11. Отслеживание в аналитике
  12. FAQ

Зачем нужны pop-up

  • Захват уходящего трафика. Пользователь почти ушёл — последний шанс предложить ценность.
  • Сбор email-базы. «Получите чек-лист бесплатно» — обмен email на полезный материал.
  • Конверсия колеблющихся. Скидка в pop-up может подтолкнуть к покупке.
  • Анонсы и срочные сообщения. Распродажа, новый продукт, акция.

При правильном использовании конверсия pop-up — 3-8% от посетителей. При неправильном — раздражают и отгоняют пользователей. Грань тонкая.

Типы pop-up по триггеру

  1. По времени. Появляется через N секунд после загрузки.
  2. По скроллу. Появляется при проматывании до определённого % страницы.
  3. Exit-intent. Появляется при движении мыши к верхнему краю окна (попытка закрыть вкладку).
  4. По клику. По кнопке «Заказать звонок» открывается модалка.
  5. На второй визит. Появляется тем, кто уже был на сайте.

Базовый код модального окна

HTML-структура:

<div id="popup-overlay" class="popup-overlay">
  <div class="popup">
    <button class="popup-close" onclick="closePopup()">×</button>
    <h2>Получите скидку 15%</h2>
    <p>Оставьте email — пришлём промокод</p>
    <form id="popup-form">
      <input type="email" required placeholder="Ваш email">
      <button type="submit">Получить скидку</button>
    </form>
  </div>
</div>

CSS:

.popup-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.6);
  z-index: 1000;
  align-items: center;
  justify-content: center;
}
.popup-overlay.active { display: flex; }
.popup {
  background: white;
  padding: 2rem;
  border-radius: 12px;
  max-width: 400px;
  width: 90%;
  position: relative;
  box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
.popup-close {
  position: absolute;
  top: 0.5rem; right: 0.5rem;
  background: none;
  border: none;
  font-size: 2rem;
  cursor: pointer;
  color: #999;
}
.popup input {
  width: 100%;
  padding: 0.75rem;
  border: 1px solid #ddd;
  border-radius: 6px;
  margin: 1rem 0;
}
.popup button[type="submit"] {
  width: 100%;
  padding: 1rem;
  background: #4a5cf5;
  color: white;
  border: none;
  border-radius: 6px;
  font-weight: 600;
  cursor: pointer;
}

JS управление:

function openPopup() {
  document.getElementById('popup-overlay').classList.add('active');
}
function closePopup() {
  document.getElementById('popup-overlay').classList.remove('active');
}
// Закрытие кликом по фону
document.getElementById('popup-overlay').addEventListener('click', (e) => {
  if (e.target.id === 'popup-overlay') closePopup();
});
// Закрытие по Escape
document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') closePopup();
});
// Показать через 15 секунд
setTimeout(openPopup, 15000);

Рекомендуемая задержка: 15-30 секунд. Меньше — раздражает («только зашёл — уже впаривают»). Больше — пользователь успевает уйти.

let shown = false;
window.addEventListener('scroll', () => {
  if (shown) return;
  const scrollPercent = (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100;
  if (scrollPercent > 50) {
    openPopup();
    shown = true;
  }
});

Срабатывает при проматывании 50% страницы — посетитель явно заинтересован, момент идеальный.

let exitShown = false;
document.addEventListener('mouseleave', (e) => {
  if (exitShown) return;
  if (e.clientY < 10) {
    openPopup();
    exitShown = true;
  }
});

Срабатывает на десктопе, когда мышь уходит к закрытию вкладки. На мобильных не работает (нет курсора) — используйте вариант по таймеру или скроллу.

Менее агрессивная альтернатива модальному окну. Появляется в углу, не перекрывает основной контент.

<div class="slidein" id="slidein">
  <button class="slidein-close" onclick="closeSlideIn()">×</button>
  <h3>Подпишитесь на новости</h3>
  <p>Раз в неделю — полезные статьи.</p>
  <input type="email" placeholder="Email">
  <button>Подписаться</button>
</div>

<style>
.slidein {
  position: fixed;
  bottom: 20px; right: 20px;
  width: 320px;
  background: white;
  padding: 1.5rem;
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0,0,0,0.2);
  transform: translateY(150%);
  transition: transform 0.3s;
  z-index: 999;
}
.slidein.active { transform: translateY(0); }
.slidein-close {
  position: absolute;
  top: 5px; right: 10px;
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
}
</style>

<script>
setTimeout(() => document.getElementById('slidein').classList.add('active'), 20000);
function closeSlideIn() { document.getElementById('slidein').classList.remove('active'); }
</script>

Отправка данных формы

Подключаете обработчик из статьи про формы — Formspree, Telegram-бот, любой удобный сервис:

document.getElementById('popup-form').addEventListener('submit', async (e) => {
  e.preventDefault();
  const email = e.target.querySelector('input').value;
  // Отправка в Telegram-бот / Formspree
  const r = await fetch('https://formspree.io/f/yourId', {
    method: 'POST',
    headers: { 'Accept': 'application/json' },
    body: new FormData(e.target)
  });
  if (r.ok) {
    e.target.innerHTML = '<p>Спасибо! Промокод выслан на email.</p>';
    setTimeout(closePopup, 3000);
  }
});

Ограничение частоты показа

Показывать pop-up каждый раз — раздражает. Используйте localStorage, чтобы запоминать, кому уже показывали:

function shouldShowPopup() {
  const lastShown = localStorage.getItem('popup_last_shown');
  if (!lastShown) return true;
  const daysAgo = (Date.now() - parseInt(lastShown)) / (1000 * 60 * 60 * 24);
  return daysAgo > 7; // показывать раз в неделю
}

function markPopupShown() {
  localStorage.setItem('popup_last_shown', Date.now().toString());
}

if (shouldShowPopup()) {
  setTimeout(() => {
    openPopup();
    markPopupShown();
  }, 15000);
}

Как не раздражать посетителей

  • Не показывайте сразу. Минимум 15-20 секунд после загрузки.
  • Один pop-up за визит. Не несколько подряд.
  • Чёткий крестик. Кнопка закрытия должна быть видна сразу.
  • Закрытие кликом по фону и по Escape. Удобно для пользователя.
  • Не показывайте повторно тем, кто уже закрыл. Используйте localStorage.
  • Адаптивность. На мобильных pop-up должен быть удобным, а не на весь экран без видимого закрытия.
  • Релевантное предложение. Скидка на одежду в pop-up на сайте о ремонте — раздражает.
  • Не используйте exit-intent на мобильных. Там это просто скролл вверх — ложные срабатывания.

Отслеживание в аналитике

Отправляйте события в Метрику, чтобы видеть конверсию pop-up:

function openPopup() {
  document.getElementById('popup-overlay').classList.add('active');
  ym(СЧЁТЧИК, 'reachGoal', 'popup_shown');
}

function closePopup() {
  document.getElementById('popup-overlay').classList.remove('active');
  ym(СЧЁТЧИК, 'reachGoal', 'popup_closed');
}

// После успешной отправки
ym(СЧЁТЧИК, 'reachGoal', 'popup_converted');

FAQ

Раздражают ли pop-up пользователей?

Раздражают плохо реализованные: появляются сразу, нельзя закрыть, появляются снова и снова. Хорошо реализованные (с таймером, чётким крестиком, ограничением частоты) обычно не вызывают негатив.

Влияют ли pop-up на SEO?

Google штрафует за «интерстициалы» — pop-up на мобильных, перекрывающие основной контент сразу при заходе. Pop-up через 15+ секунд после загрузки и с возможностью закрытия не влияют на ранжирование.

Какая конверсия у pop-up формы?

Средняя — 2-5% от показавших, лучшие — до 8-10%. Зависит от релевантности предложения и аудитории.

Лучше ли платный сервис попапов или свой код?

Свой код — бесплатно, гибко, не зависит от стороннего сервиса. Платные (Popup Maker, OptinMonster) — удобный визуальный редактор, готовая аналитика, A/B-тесты. Если нужна сложная сегментация — платные оправданы.

Как сделать так, чтобы pop-up появлялся только один раз?

Через localStorage. Показали — записали флаг. При следующих визитах проверяем флаг и не показываем. Код в статье.

Можно ли сделать pop-up на мобильных?

Можно, но осторожно. На мобильных pop-up более раздражающий из-за маленького экрана. Используйте слайдер снизу вместо модального окна, либо появляйтесь после 30+ секунд активного использования.

Что предлагать в pop-up для максимальной конверсии?

Конкретную ценность взамен email: скидка с промокодом, чек-лист, бесплатная консультация, бонусный контент. Чем конкретнее — тем выше конверсия. Просто «подпишитесь на нас» работает плохо.

Заключение

Pop-up формы — мощный инструмент для увеличения конверсии лендинга, если использовать аккуратно. Чистый JS-код в этой статье даёт всё необходимое: модальное окно, разные триггеры (таймер, скролл, exit-intent), ограничение частоты, отправка данных. Без зависимости от платных сервисов и плагинов.

Многие HTML-шаблоны из подборки Zettabyte уже идут с готовыми pop-up блоками — остаётся настроить под свои задачи. А для размещения сайта подойдёт любой тариф из подборщика хостингов.