Пару слов о сути.
Всем привет. Сегодня хочу показать простой ну многим желанный скрипт на свой сайт - всплывающее фейковое действие на сайте. Ну, типа Василий из Москвы только что купил дрель и прочее. Да, наверное, где-то в другой вселенной есть и те кто реальные действия на сайте показывает, но это не про нас 😁
Стек:
Писать скрипт мы будет естественно на нашем любимом javascript, так как быстро, просто и легко интегрируется в любые сайты. Не важно, самописный у вас проект или какой-либо ВордПресс (да-да, приучаемся к русскоязычным наименованиям с 1 марта😎)
Суть данного блога не показать поэтапно что за что отвечает, а дать готовое решение, но код достаточно прокомментирован и разберется с ним любой школьник.
notifications.js
Логика всего решения находится в одном файле, код ниже. Можно посмотреть что за что отвечает и всё в принципе понять.
document.addEventListener('DOMContentLoaded', () => {
// === НАСТРОЙКИ ===
const jsonUrl = '/templates/Default/js/notifications.json'; // Путь к вашему JSON файлу
const minDelay = 25000; // Минимальное время между уведомлениями (в миллисекундах, 5000 = 5 сек)
const maxDelay = 50000; // Максимальное время (в миллисекундах)
const displayTime = 5000; // Сколько времени висит само уведомление
// =================
let notifications = [];
// Создаем контейнер для уведомлений (чтобы они выстраивались один за другим, если наложатся)
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.top = '20px'; // Отступ сверху
container.style.right = '20px'; // Отступ справа
container.style.zIndex = '99999'; // Поверх всего сайта
container.style.display = 'flex';
container.style.flexDirection = 'column';
container.style.gap = '10px';
container.style.pointerEvents = 'none'; // Чтобы не блокировать клики по сайту сквозь прозрачные зоны
// Медиазапрос для мобильных устройств (чтобы всплывало снизу на мобилках)
if (window.innerWidth <= 768) {
container.style.top = 'auto';
container.style.bottom = '20px';
}
document.body.appendChild(container);
// Загружаем данные из JSON
fetch(jsonUrl)
.then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.json();
})
.then(data => {
notifications = data;
if (notifications.length > 0) {
scheduleNextNotification(); // Запускаем цикл, когда данные загрузились
}
})
.catch(err => console.error('Ошибка загрузки notifications.json:', err));
// Функция планирования следующего показа
function scheduleNextNotification() {
// Случайное время ожидания
const delay = Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
setTimeout(() => {
showNotification();
scheduleNextNotification();
}, delay);
}
// Функция отрисовки одного уведомления
function showNotification() {
// Выбираем случайную запись из базы
const randomIndex = Math.floor(Math.random() * notifications.length);
const item = notifications[randomIndex];
// Создаем плашку
const popup = document.createElement('div');
popup.style.background = '#ffffff';
popup.style.boxShadow = '0 10px 25px rgba(0,0,0,0.15)';
popup.style.borderRadius = '10px';
popup.style.padding = '15px';
popup.style.minWidth = '260px';
popup.style.maxWidth = '320px';
popup.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
popup.style.display = 'flex';
popup.style.alignItems = 'center';
popup.style.borderLeft = '5px solid #0EA8A0'; // Синяя полоса слева (можно поменять цвет на фирменный)
popup.style.pointerEvents = 'auto'; // Включаем клики для самой плашки
// Начальная позиция для анимации
const transformValue = window.innerWidth <= 768 ? 'translateY(120%)' : 'translateX(120%)';
popup.style.transform = transformValue;
popup.style.transition = 'transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.5s ease';
popup.style.opacity = '0';
// Иконка слева
const icon = document.createElement('div');
icon.innerHTML = '🔥';
icon.style.fontSize = '24px';
icon.style.marginRight = '12px';
// Текстовый блок
const textContainer = document.createElement('div');
// Имя клиента
const titleSpan = document.createElement('div');
titleSpan.innerHTML = `<strong>${item.name}</strong>`;
titleSpan.style.marginBottom = '2px';
titleSpan.style.color = '#333';
titleSpan.style.fontSize = '14px';
// Действие клиента
const actionSpan = document.createElement('div');
actionSpan.textContent = item.action;
actionSpan.style.color = '#666';
actionSpan.style.fontSize = '13px';
actionSpan.style.lineHeight = '1.3';
textContainer.appendChild(titleSpan);
textContainer.appendChild(actionSpan);
// Крестик закрытия
const closeBtn = document.createElement('div');
closeBtn.innerHTML = '×';
closeBtn.style.position = 'absolute';
closeBtn.style.top = '5px';
closeBtn.style.right = '10px';
closeBtn.style.cursor = 'pointer';
closeBtn.style.fontSize = '18px';
closeBtn.style.color = '#999';
closeBtn.onclick = () => {
popup.style.transform = transformValue;
popup.style.opacity = '0';
setTimeout(() => {
if (popup.parentElement) popup.parentElement.removeChild(popup);
}, 500);
};
popup.appendChild(icon);
popup.appendChild(textContainer);
popup.appendChild(closeBtn);
container.appendChild(popup);
// Запускаем анимацию выезда
requestAnimationFrame(() => {
popup.style.transform = 'translate(0)';
popup.style.opacity = '1';
});
// Запускаем анимацию скрытия и удаления
setTimeout(() => {
if (popup.parentElement) {
popup.style.transform = transformValue;
popup.style.opacity = '0';
setTimeout(() => {
if (popup.parentElement) popup.parentElement.removeChild(popup);
}, 500);
}
}, displayTime);
}
});
notifications.json
Файлик, в котором мы будем хранить то что будет показывать по очереди на нашей странице.
[
{
"name": "Елена, г. Москва",
"action": "только что записалась на сложное окрашивание"
},
{
"name": "Ольга, г. Санкт-Петербург",
"action": "оплатила курс биоревитализации"
},
{
"name": "Мария, г. Казань",
"action": "купила профессиональный уход за лицом"
},
{
"name": "Анна, г. Екатеринбург",
"action": "сделала маникюр премиум-класса"
},
{
"name": "Светлана, г. Новосибирск",
"action": "оставила заявку на подбор образа"
},
{
"name": "Татьяна, г. Сочи",
"action": "забронировала сеанс в термальном СПА"
},
{
"name": "Ирина, г. Краснодар",
"action": "только что сделала наращивание ресниц"
},
{
"name": "Наталья, г. Самара",
"action": "оформила подписку на бьюти-бокс"
},
{
"name": "Юлия, г. Нижний Новгород",
"action": "записалась на массаж Гуаша"
},
{
"name": "Виктория, г. Ростов-на-Дону",
"action": "купила подарочный сертификат на услуги стилиста"
}
]
Подключение
Ну вот собственно и весь скрипт, который нам теперь только останется подключить внизу до закрывающегося тега </body> обычным способом:
<script src="notifications.js"></script>
А на этом всё. Если был полезен, буду рад реакции и комментарию 🥰
Комментарии
0Оставить комментарий