Всплывающие сообщения для сайта на чистом JavaScript

Статья, в которой рассмотрим, как можно самостоятельно создать для сайта всплывающие сообщения (уведомления) подобно тому, как это выполняет jGrowl (плагин для jQuery).
Исходные коды
Всплывающие сообщения – это ненавязчивый способ показа сообщений для пользователя. Они позволяют отображать уведомления пользователю заметным образом и не мешая при этом его взаимодействию с сайтом или веб-приложением.
Проект, рассматриваемый в рамках этой статьи, расположен на Github по адресу: https://github.com/itchief/ui-components/tree/master/toast
Он написан на чистом JavaScript без использования сторонних библиотек.
По умолчанию всплывающие сообщения отображаются в правом верхнем углу. При этом они могут выводиться как с заголовком, так и без него.

Подключение и использование
Компонент для показа всплывающих уведомлений состоит из 2 файлов: «toast.css» и «toast.js». Преимуществом данной библиотеки состоит в том, что она имеет очень маленький размер («toast.min.js» немного больше 1Кбайта). В отличие от библиотеки jGrowl эти сообщения не требуют библиотеку jQuery, что для многих сайтов очень важно.
Подключение компонента осуществляется посредством:
- включения на страницу стилей «toast.min.css»;
- добавления JavaScript кода «toast.js».
<link href="path/to/toast.min.css" rel="stylesheet">
<script src="path/to/toast.min.js"></script>
Вывод всплывающего сообщения на страницу осуществляется посредством создания экземпляра объекта Toast
:
/*
title - название заголовка
text - текст сообщения
theme - тема
autohide - нужно ли автоматически скрыть всплывающее сообщение через interval миллисекунд
interval - количество миллисекунд через которые необходимо скрыть сообщение
*/
new Toast({
title: 'Заголовок',
text: 'Сообщение...',
theme: 'light',
autohide: true,
interval: 10000
});
Если нужно создать сообщение без заголовка, то нужно просто ключу title
установить значение false
:
// без заголовка
new Toast({
title: false,
text: 'Сообщение...',
theme: 'light',
autohide: true,
interval: 10000
});
Подробное описание
Создание HTML кода всплывающих сообщений как с заголовком, так и без него выполняется в JavaScript. Целью является создание следующей структуры:
<!-- без заголовка -->
<div class="toast toast_message toast_default">
<div class="toast__body">Сообщение...</div>
<button class="toast__close" type="button"></button>
</div>
<!-- с заголовком -->
<div class="toast toast_default">
<div class="toast__header">Заголовок</div>
<div class="toast__body">Сообщение...</div>
<button class="toast__close" type="button"></button>
</div>
HTML код сообщений простой. Он состоит из элемента с классом toast
, в котором в зависимости от типа уведомления расположены два или три элемента:
<div>
с классомtoast__header
- заголовок;<div>
с классомtoast__body
- элемент, в котором выводится само сообщение;<button>
с классомtoast__close
- кнопка, для закрытия сообщения.
С помощью классов в CSS добавляются стили к этим элементам:
/* CSS-переменные */
:root {
--toast-border-radius: 0.25rem;
--toast-theme-default: #fff;
}
.toast {
font-size: 0.875rem;
background-clip: padding-box;
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: var(--toast-border-radius);
box-shadow: 0 .125rem .25rem rgba(0, 0, 0, 0.075);
display: none;
position: relative;
overflow: hidden;
}
.toast_default {
color: #212529;
background-color: var(--toast-theme-default);
}
.toast:not(:last-child) {
margin-bottom: 0.75rem;
}
.toast__header {
position: relative;
padding: 0.5rem 2.25rem 0.5rem 1rem;
background-color: rgba(0, 0, 0, 0.03);
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.toast__close {
content: "";
position: absolute;
top: 0.75rem;
right: 0.75rem;
width: 0.875em;
height: 0.875em;
background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/0.875em auto no-repeat;
border: 0;
opacity: 0.5;
cursor: pointer;
transition: opacity 0.1s ease-in-out;
}
.toast__close:hover {
opacity: 1;
}
.toast__body {
padding: 1rem;
}
.toast_message .toast__body {
padding-right: 2.25rem;
}
Класс toast__close
ещё используется в обработчике события click
. При нажатию на эту кнопку выполняется закрытие сообщения.
this._el.addEventListener('click', (e) => {
if (e.target.classList.contains('toast__close')) {
// вызываем метод, скрывающий сообщение
this._hide();
}
});
После того как JavaScript добавляет HTML код всплывающего сообщения на страницу, оно не отображается, т.к. по умолчанию оно имеет display: none
. Его показ осуществляется после того, как к нему добавляется класс toast_show
.
.toast_show {
display: block;
}
Скрытие сообщения выполняется путём удаления класса toast_show
.
Задание темы осуществляется посредством добавления класса.
Например, тема primary устанавливается так:
<div class="toast toast_primary">...</div>
Помещение элементов .toast
выполняется в контейнер .toast-container
. Его создание тоже осуществляется с помощью JavaScript, но только в том случае, если его нет на странице.
if (!document.querySelector('.toast-container')) {
const container = document.createElement('div');
container.classList.add('toast-container');
document.body.append(container);
}
Данный элемент по умолчанию располагается в правом верхнем углу страницы и имеет ширину 270 пикселей. Если нужно расположить в другом месте, то измените стили.
:root {
--toast-width: 270px;
}
.toast-container {
position: fixed;
top: 15px;
right: 15px;
width: var(--toast-width);
}
Написан код JavaScript в виде класса и имеет следующую структуру:
class Toast {
constructor(params) { ... }
_show() { ... }
_hide() { ... }
_create() { ... }
}
Добрый день.
Разобрался как вывести сообщение.Не могу понять, как скрыть сообщение из JS, если не стоит autohide?
Пробую Не работает.Поставил в toast__body для обработки html — innerHTML
Но вот проблема, уведомления у меня динамически, т.е. разные, выводятся в зависимости от типа и привязан вывод к id=«error», div id=«error»> </div, проблема в том что уведомления когда исчезают то их «тело» просто скрывается, и получается наслоение div id=«error»> </div, мой скрипт отправляет ошибку в первый блок div id=«error»> </div, а он, если уведомления уже были до этого, скрыт, и получается что у меня div class=«toast__body»>div id=«error»> </div</div пустой, а сообщение об ошибку в скрытом предыдущем уведомлении.
Вопрос: можно ли как то делать reset уведомления или уничтожать их после сокрытия.
script >
new Toast({
title: false,
text: 'Сообщение...',
theme: 'light',
autohide: true,
interval: 10000
});
Toast.destroy(); или Toast.reset(); — не работает
</ script
извиняюсь за код, не знаю как его по другому вставить, удалил < что бы отобразился)
Здесь 3 условия:
— если мы сегодня не показывали
— если это будний день
— если время больше 12 и меньше 16
Если хотя бы одно из условий ложно, то оповещение не показываем.
Подскажите, пожалуйста, что я делаю не так и как внедрить это на своем сайте?
Статьи расписаны легко и приятны для чтения. Спасибо Вам)
В этом коде после загрузки получаем значение по ключу toast-time, содержащее время последнего показа сообщения. Если его нет, или прошло уже три часа, то показываем сообщение и записываем новое значение времени в LocalStorage. Если нужно через 20 переходов, то аналогично.
Добавить звуковое оповещение можно так:
Пример со звуком можно посмотреть здесь.
Пример доступен по этой ссылке.
А возможно к Toast добавить ещё и звуковое оповещение?