Статья, в которой рассмотрим, как можно самостоятельно создать для сайта всплывающие сообщения (уведомления) подобно тому, как это выполняет jGrowl (плагин для jQuery).

Проект, рассматриваемый в рамках этой статьи, расположен на Github по адресу: https://github.com/itchief/how-to/tree/master/toast

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

В этом проекте рассмотрим создание библиотеки для всплывающих сообщений (уведомлений) как с использованием jQuery, так и без него (т.е. на «чистом» JavaScript).

Внешний вид всплывающих сообщений

В рамках этого проекта выполним создание 2 вариантов сообщений (с заголовком и без него).

Всплывающие сообщения (уведомления) для сайта (2 варианта)

По умолчанию сообщения будем выводить в правом верхнем углу страницы.

Описание использования созданной библиотеки для всплывающих сообщений

Библиотека для всплывающих сообщений состоит из 2 файлов ("toast.css" и "toast.js"). Преимуществом данной библиотеки является то, что она имеет очень маленький объем (менее 3Кбайт). В отличие от библиотеки jGrowl данный проект имеет реализацию всплывающих сообщений без использования библиотеки jQuery. Что является для некоторых проектов очень важным.

Подключение библиотеки для создания всплывающих сообщений к странице

Подключение библиотеки для создания уведомлений на страницу осуществляется посредством:

  • подключения CSS файла «toast.css» или «toast-with-header.css» к странице или включения содержимого одного из этих файлов в свой файл стилей;
  • добавления JavaScript файла «toast.js» или «toast-with-header.js» на страницу с помощью элемента script или включения содержимого одного из этих файлов в свой файл скриптов.
...
<link href="path/to/toast.css" rel="stylesheet">
...

<script src="path/to/toast.js"></script>

Создание всплывающих сообщений

Добавление на страницу всплывающих сообщений осуществляется посредством вызова статического метода add функции-конструктора Toast:

Синтаксис кода для всплывающих сообщений с заголовком:

/*
Параметры функции add:
header (строка) - название заголовка
body (строка) - текст сообщения
color (строка) - цвет в формате #rrggbb
autohide (булево) - скрывать ли автоматически всплывающее сообщение
delay (число) - количество миллисекунд, после которых сообщение будет автоматически скрыто
*/
Toast.add({
header: 'Название заголовка',
body: 'Текст сообщения',
color: '#28a745',
autohide: true,
delay: 10000
});  

Для сообщений без заголовка:

/*
Параметры функции add:
text (строка) - текст сообщения
color (строка) - цвет в формате #rrggbb
autohide (булево) - скрывать ли автоматически всплывающее сообщение
delay (число) - количество миллисекунд, после которых сообщение будет автоматически скрыто
*/
Toast.add({
text: 'Текст сообщения...',
color: '#28a745',
autohide: true,
delay: 5000
});

Как разработать всплывающие сообщения для сайта

В этом проекте созданы различные варианты всплывающих сообщений. Подробно разберём только вариант, в котором они построены на "чистом" JavaScript и имеют внешний вид «без заголовка».

Создание всплывающих уведомлений начнём с разработки их HTML структуры:

<!-- HTML -->  
<div class="toast">
Текст сообщения...
<button class="toast__close" type="button">&times;</button>
</div>

Как видно, HTML синтаксис сообщений очень прост. Он состоит из элемента div с классом toast и button с toast-close.

Данные классы используются не только для оформления элементов, но и в коде JavaScript.

В CSS вышеприведённые классы применяются для привязки к HTML элементам следующих стилей:

/* CSS */ 
.toast {
overflow: hidden;
font-size: 0.875rem;
background-color: rgba(255, 255, 255, 0.5);
background-clip: padding-box;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 0.25rem;
box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
display: none;
position: relative;
padding: 0.75rem 2rem 0.75rem 0.75rem;
overflow-wrap: break-word;
word-break: break-word;
}

.toast__close {
position: absolute;
top: 0;
right: 10px;
padding: 0;
background-color: transparent;
border: 0;
cursor: pointer;
float: right;
font-size: 1.5rem;
font-weight: 700;
line-height: 1;
color: #000;
text-shadow: 0 1px 0 #fff;
opacity: 0.6;
appearance: button;
margin: 0;
font-family: inherit;
border-radius: 0;
}

Добавлять сообщения (HTML код) на страницу будем динамически (с помощью JavaScript).

Класс "toast__close" в JavaScript будем использовать в роли селектора для получения кнопки "Закрыть". Для данной кнопки добавим обработку события "click". В обработчике этого события напишем действия, при выполнении которых будет осуществляться закрытие (скрытие) этого сообщения.

По умолчанию всплывающие сообщения после добавления их на страницу не отображаются ("display: none"). Отображение сообщения выполняется посредством добавления к нему класса "toast_show".

/* CSS */ 
.toast_show {
display: block;
}  

Для скрытия отображаемого сообщения у него просто необходимо удалить класс "toast_show".

Задание цвета всплывающему сообщению будем осуществлять посредством "инлайнового" (с помощью атрибута "style") добавления к элементу с классом "toast" CSS-свойства background-color.

<!-- HTML -->
<div class="toast" style="background-color: rgba(255, 255, 255, 0.5);">
Текст сообщения...
<button class="toast__close" type="button">&times;</button>
</div>

Помещать создаваемые с помощью JavaScript всплывающие сообщения будем в контейнер (элемент) div с классом "toasts". Данный контейнер будем добавлять на страницу тоже с помощью JavaScript. Но осуществлять это будем только в том случае, если на странице его ещё нет.

HTML синтаксис контейнера:

<!-- HTML -->
<div class="toasts" style="position: fixed; top: 15px; right: 15px; width: 250px;"></div>    

Данный элемент по умолчанию настроен так, что он располагается в правом верхнем угла окна браузера и имеет ширину 250 пикселей. Если его нужно расположить в другом месте, то эти CSS свойства необходимо изменить в JavaScript.

Дополнительно в CSS добавим ещё следующий код. Он необходим для того чтобы задать отступ между сообщениями по вертикали.

.toast:not(:last-child) {
margin-bottom: 0.75rem;
}

Код JavaScript состоит из функции-конструктора Toast, методов show и hide, и двух статических функций create и add.

// код JavaScript 
// функция-конструктор Toast (для создания объектов Toast)
var Toast = function (element, config) {
// приватные переменные класса Toast
var
  _this = this,
  _element = element,
  _config = {
    autohide: true,
    delay: 5000
  };
// установление _config
for (var prop in config) {
  _config[prop] = config[prop];
}
// get-свойство element
Object.defineProperty(this, 'element', {
  get: function () {
    return _element;
  }
});
// get-свойство config
Object.defineProperty(this, 'config', {
  get: function () {
    return _config;
  }
});
// обработки события click (скрытие сообщения при нажатии на кнопку "Закрыть")
_element.addEventListener('click', function (e) {
  if (e.target.classList.contains('toast__close')) {
    _this.hide();
  }
});
}
// методы show и hide, описанные в прототипе объекта Toast
Toast.prototype = {
show: function () {
  var _this = this;
  this.element.classList.add('toast_show');
  if (this.config.autohide) {
    setTimeout(function () {
      _this.hide();
    }, this.config.delay)
  }
},
hide: function () {
  this.element.classList.remove('toast_show');
}
};
// статическая функция для Toast (используется для создания сообщения)
Toast.create = function (text, color) {
var
  fragment = document.createDocumentFragment(),
  toast = document.createElement('div'),
  toastClose = document.createElement('button');
toast.classList.add('toast');
toast.style.backgroundColor = 'rgba(' + parseInt(color.substr(1, 2), 16) + ',' + parseInt(color.substr(3, 2), 16) + ',' + parseInt(color.substr(5, 2), 16) + ',0.5)';
toast.textContent = text;
toastClose.classList.add('toast__close');
toastClose.setAttribute('type', 'button');
toastClose.textContent = '×';
toast.appendChild(toastClose);
fragment.appendChild(toast);
return fragment;
};
// статическая функция для Toast (используется для добавления сообщения на страницу)
Toast.add = function (params) {
var config = {
  header: 'Название заголовка',
  text: 'Текст сообщения...',
  color: '#ffffff',
  autohide: true,
  delay: 5000
};
if (params !== undefined) {
  for (var item in params) {
    config[item] = params[item];
  }
}
if (!document.querySelector('.toasts')) {
  var container = document.createElement('div');
  container.classList.add('toasts');
  container.style.cssText = 'position: fixed; top: 15px; right: 15px; width: 250px;';
  document.body.appendChild(container);
}
document.querySelector('.toasts').appendChild(Toast.create(config.text, config.color));
var toasts = document.querySelectorAll('.toast');
var toast = new Toast(toasts[toasts.length - 1], { autohide: config.autohide, delay: config.delay });
toast.show();
return toast;
}

Создание сообщений и их отображение пользователю выполняется с помощью вызова статической функции add:

// JavaScript
/*
Параметры функции add:
text (строка) - текст сообщения
color (строка) - цвет в формате #rrggbb
autohide (булево) - скрывать ли автоматически всплывающее сообщение
delay (число) - количество миллисекунд, после которых сообщение будет автоматически скрыто
*/
Toast.add({
text: 'Текст сообщения...',
color: '#dc3545',
autohide: false
});

Статическая функция add функции-конструктора Toast выполняет следующие действия:

  • создаёт контейнер для сообщений (элемент "div" с классом "toasts") и добавляет его перед закрывающим тегом "body";
  • добавляет в конец контейнера новое сообщение (toast) с помощью вызова статической функции Toast.create();
  • создает объект "Toast" посредством вызова функции-конструктора "Toast" (new Toast()) и сохраняет ссылку на данный объект в переменную toast;
  • вызывает метод "show" объекта toast (данный метод включает отображения уже созданного с помощью Toast.create() всплывающего сообщения);
  • возвращает в качестве результата выполнения ссылку на созданный объект (toast).