Pull to refresh

Модальное окно, которое вы ждали. Или как вызвать «всплывашку» с разных кнопок на чистом JS

Reading time 3 min
Views 23K
Добрый день! Меня зовут Черепанов Борис, я занимаюсь разработкой сайтов на wordpress и bitrix. Я тут над проектом работал. Одно из ограничений было не использовать jquery, а мне нужно было вызвать одно и тоже модальное окно с разных кнопок. Собственно, это довольно простая задача, но я решил пойти дальше и сделать модальное окно, которое бы создавалось при первом клике, сохраняло своё состояние, имело конструктор для вызова и т.д. И в итоге я не пожалел. Объясню почему позже. Я «обернул» это модальное окно в готовое решение, которое можно использовать постоянно.

Установка


Установить такую «модалку» просто. Скачиваете js-файл и подключаете. Он не зависит от каких-то событий или библиотек, так что можете подключать где вам нужно. Вот ссылка на github

Инициализация


На той странице на которой вам нужно вызвать вы пишите в js:

new XMC({
    bodyID: 'body',
    backgroundLayerID: 'wrapper',
    selector: 'data-type',
    selectorValue: 'openModalForm',
    btnId: 'mfClose',
    content: 'Привет',
    classListBg: ['zuzu', 'zaza'],
    classListBody: ['zuzu', 'zaza2'],
    classListBtn: ['zuzu', 'zaza3'],
    styleBg: {
        top: '0',
        left:'0',
        right: '0',
        bottom: '0',
        position: 'fixed',
        background: '#00000090',
        justifyContent: 'center',
        alignItems: 'center',
        zIndex: '6'
    },
    styleBody: {
        minWidth: '200px',
        minHeight: '200px',
        background: '#ffffff',
        justifyContent: 'center',
        alignItems: 'center',
    },
    btnStyle: {
        width: '40px',
        height: "40px",
        background: '#ffffff',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        position: 'absolute',
        top: '5%',
        right: '5%',
        cursor: 'pointer'
    }
});

Подробнее о пунктах в объекте


Есть 6 обязательных пунктов:

  • bodyID – это идентификатор блока в котором будет содержаться контент модального окна
  • backgroundLayerID – id затемняющего слоя
  • selector – html атрибут который будет у всех кнопок которые будут вызывать модальное окно
  • selectorValue – значение селектора
  • bntID – id кнопки закрытия модального окна
  • content – текст или html внутри модального окна

Необязательные, но очень важные пункты:

  • classListBg, classListBody, classListBtn – массивы классов для затемняющего слоя, основного окна и кнопки закрыть соответственно
  • styleBg, styleBody, btnStyle – объекты со стилями затемняющего слоя, основного окна и кнопки закрыть соответственно

Немного о самом модальном окне


Я уже говорил, что основная задача, которую решает это модальное окно — это вызов с нескольких кнопок. Клик по нескольким кнопка для вызова js это типичный пример делегирования и в XMC (так я назвал своё модальное окно) оно реализовано так:

XMC.prototype.delegateClick = function () {
    var mf = this;
    window.addEventListener('click', function () {
// Проверяю есть ли у элемента, на который я нажимаю соответствующий атрибут и его значение
if(event.target.hasAttribute(mf.selector) && event.target.getAttribute(mf.selector) === mf.selectorValue ){
               mf.show(); // Показываю модальное окно
               mf.delegateClose(); // Вешаю обработчик на закрытие
           }
    }, mf, false);
};

Соответственно и в конструкторе нужно прописать:

var XMC = function (object) {
/* Прочий код */

this.delegateClick();

}

Кстати, в своё время, мне помогла с этим разобраться статья с learn javascript. Ознакомиться с ней будет полезным.

AJAX для формы


В моём «кейсе» необходимо было загружать форму по ajax (эта задача появилась в процессе). Благодаря моему изначальному подходу мне удалось сэкономить не мало времени. Я расширил через прототип.

XMC.prototype.ajax = function () {
    var mf = this;
    var data = new Object();
// Немного вырезал, не хочу показывать данные, которые я отправлял
    data = JSON.stringify(data);
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function () {
        if(this.readyState == 4 && this.status == 200){
            mf.body.innerHTML = this.responseText;
            mf.sendClickDelegate(mf.form);
            mf.i18n();
        }
    };
    xhttp.open('POST', localizationPreloader.adminUrl + "?action=my_action", true);
    xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhttp.send("data="+data);
    return this;
}

Такой код запроса у меня был для CMS Wordpress.

Итог


В итоге благодаря объектному подходу у меня получилось сделать не просто всплывающие окно, а почти web-приложение в котором у меня 2 ajax для получения формы и отправки, перевод в зависимости от браузера, чтение cookie, анимация загрузки. Благодаря этому же мне не пришлось искать новые элементы по различным селекторам для перевода или работы с данными формы, которая «прилетела» по ajax.

Надеюсь, что для вас будет полезна моя статья. Удачи!
Tags:
Hubs:
-2
Comments 58
Comments Comments 58

Articles