Йоу-йоу! Занимался я очень долго одним проектом, в котором много JS и моё большое желание не использовать jQuery. Настал тот момент, когда мне стало нужно вызывать модальное окно с разных кнопок. А еще нужно было динамически создавать модальное окно. И вместо использования готовых модальных окон, я решил сделать своё в объектно-ориентированном стиле. Наверное для тех кому нужно такое всплывающие окно самое важное это сделать вызов с разных кнопок. Об этом я и расскажу в первую очередь.
Вообще подобная задача — это типичный пример делегирования события. И вот мой пример:
var XMC = function (object){ // Конструктор this.delegateClick(); } XMC.prototype.delegateClick = function () { // Это нужно потому что в событие this другое значение var mf = this; // Вешаю событие на window window.addEventListener('click', function (event) { // Проверяю есть ли у элемента нужный атрибут и правильное ли у него значение if(event.target.hasAttribute(mf.selector) && event.target.getAttribute(mf.selector) === mf.selectorValue ){ // Открываю окно mf.show(); } }, mf, false); return this; };
Думаю, что часть читателей этой статьи закроют её, так как уже поняли то что им нужно. А для ленивых, которые не хотят возиться с кодом, я выложил ссылку на github с примером и сейчас расскажу как этим пользоваться.
Ничего особенного делать не нужно, копируете код с моего github и вставляете из файла xmcmodal.js. Подключаем его как обычный скрипт. Приступим к инициализации. В файле, на который я дал вам ссылку, уже есть пример. Я расскажу что к чему. Смотрите код и комментарии
new XMC({ // ID для блока, в котором будет контент модального окна bodyID: 'tModlaContentBox', // ID заднего слоя backgroundLayerID: 'tModalContentWraper', // Селектор который будет у всех элементов, которые будут вызывать окно selector: 'data-type', // Значение селектора selectorValue: 'openModalForm', // ID для кнопки закрыть btnId: 'fbgmfClose', // html во всплывающем окне или текст content: 'wait...', // Классы для заднего слоя 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: '11000' }, // Стили для блока с контентом 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', zIndex: '7' } });
Конструктор получился очень гибким. В нём можно указать всё что нужно, а потом динамически менять.
Сейчас в моём модальном окне 149 строк кода, если считать с пробелами. Но в конечном счёте, в моём проекте оно выросло до 367 строк и я рад этому. В начале моего проекта мне нужно было просто модальное окно. Но потом мне понадобилось загружать в него форму с contact form 7 по ajax, так же и отправлять данные, валидировать форму, переводить форму на 2 языка, проверять куки. И с XMC (название моего модального окна) это очень просто, потому что ты не ищешь элементы, не назначаешь множество переменных. У тебя всё хранится внутри объекта и ты имеешь доступ к его данным. Вот например как я сделал 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.form = mf.body.firstChild; mf.form = mf.form.querySelector('form'); mf.form.setAttribute('action', '#wpcf7-f41-o1'); var el = document.createElement('div'); el.id = 'wpcf7-f41-o1'; mf.body.appendChild(el); if(window.screen.width < '758'){ var submit = mf.form.querySelector('input[type="submit"]'); mf.btnClose.classList.add('btn'); mf.btnClose.setAttribute('type', 'button'); mf.btnClose.classList.add('btn-warning'); mf.btnClose.classList.add('rounded-circle'); submit.insertAdjacentElement('afterend', mf.btnClose); } mf.sendClickDelegate(mf.form); mf.i18n(); } }; xhttp.open('POST', localizationPreloader.adminUrl + "?action=fgb_modal_one_form", true); xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhttp.send("data="+data); return this; };
this.body — это основной блок «модалки», в которую по ajax подгружаю форму. А сам ajax я вызываю initBackground() в условии если задний слой равен null. Этим я достигаю того, что ajax форма делается один раз, а не каждый раз как происходит нажатие.