Наверх
К списку статей

Мой блог

Фейковое всплывающее уведомление о действии на сайте

Пару слов о сути.

Всем привет. Сегодня хочу показать простой ну многим желанный скрипт на свой сайт - всплывающее фейковое действие на сайте. Ну, типа Василий из Москвы только что купил дрель и прочее. Да, наверное, где-то в другой вселенной есть и те кто реальные действия на сайте показывает, но это не про нас 😁

Стек:

Писать скрипт мы будет естественно на нашем любимом 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 = '&times;';
        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

Оставить комментарий

Комментарий появится на странице после проверки модератором.

Пока нет комментариев. Будьте первым!

К списку статей