UNPKG

js.popuper

Version:

CSS smart sticky position for exceeding aside blocks

183 lines (140 loc) 6.39 kB
/** * Всплывающие окна уведомления. * * @param {string} title - уникальное название всплывающего окна передаётся в data атрибут * @param {string} body - основной текст тела окна * @param {Array} contols - массив объектов кнопок * @returns{undefined} */ // Вызов // new PopUper({ // title: 'Заголовок в header', // body: 'Основной текст или HTML', // style: 'CSS Class', // controls: [ // { // title: 'да', // action: ()=>{ // console.log('sdsdsd'); // }, // enter: true, // }, // { // title: 'нет', // action: ()=>{console.log('нет');}, // }, // ], // }) class PopUper { constructor(params){ // Создание глобального массива попаперов window.popUpers || (window.popUpers = []); // Создание объекта свойств попапера this.options = params || {}; !this.options.id && (this.options.id = parseInt(new Date().getTime())); !this.options.body && (this.options.body = 'Hello'); !this.options.title && (this.options.title = ''); this.enterAction = this.enterAction.bind(this); this.keyEscape = this.keyEscape.bind(this); this._body = this.createEl('div', 'popuperWrap'); this._body.setAttribute('data-popuperName', this.options.id); // Создаём элементы попапера this._body._popuper = this.createEl('div', `popuper`); if(this.options.style) this._body._popuper.classList.add(this.options.style); this._body._popuperHeader = this.createEl('div', 'popuper__header'); this._body._close = this.createEl('div', 'popuper__close'); this._body._close.addEventListener('click', ()=> this.close() ); this._body._close.innerHTML = ` <svg version="1.1" id="cross" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve"> <path d="M7,26c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l18-18c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-18,18C7.5,25.9,7.3,26,7,26z"/> <path d="M25,26c-0.3,0-0.5-0.1-0.7-0.3l-18-18c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l18,18c0.4,0.4,0.4,1,0,1.4C25.5,25.9,25.3,26,25,26 z"/> </svg> `; if(this.options.title){ this._body._title = this.createEl('div', 'popuper__title'); this._body._title.innerText = this.options.title; this._body._popuperHeader.appendChild(this._body._title) } this._body._popuperHeader.appendChild(this._body._close); this._body._popuper.appendChild(this._body._popuperHeader); this._body._popUperbody = this.createEl('div', 'popuper__body'); this._body._popUperbody.innerHTML = this.options.body; this._body._popuper.appendChild(this._body._popUperbody); this.enterActionArray = []; // Формирование кнопок if(this.options.controls){ this._body._controls = this.createEl('div', 'popuper__controls'); this.options.controls.forEach( control => { let controlElement = this.createEl('button'); controlElement.innerHTML = control.title; if(control.style){ controlElement.classList.add(control.style); } controlElement.addEventListener('click', ()=>{ if(control.action){ control.action() } if(control.close != false){ this.close(); } }); if(control.enter){ if(control.action) this.enterActionArray.push(control.action); document.addEventListener('keydown', this.enterAction); } this._body._controls.appendChild(controlElement); }); this._body._popuper.appendChild(this._body._controls); } // *** Формирование кнопок this._body.appendChild(this._body._popuper); document.body.appendChild(this._body); // Добавление текущего попапера в глобальный массив попаперов document.addEventListener('keydown', this.keyEscape); window.popUpers.push(this); if(window.popUpers.length == 1 && !document.body.classList.contains('--fixed')){ if(window.innerWidth - document.body.clientWidth){ document.body.style.paddingRight = window.innerWidth- document.body.clientWidth + 'px'; } document.body.classList.add('--fixed'); } } enterAction(event) { if (event.code === 'Enter' || event.code === 'NumpadEnter') { this.enterActionArray.forEach(item => { item(); }) this.close(); }; } keyEscape (event) { if(event.code === 'Escape'){ window.popUpers[window.popUpers.indexOf(this)].close(); }; } close() { this._body.remove(); window.popUpers.splice(window.popUpers.indexOf(this), 1) if(this.enterActionArray){ document.removeEventListener('keydown', this.enterAction); } // window.popUpers.pop(); if(window.popUpers.length == 0){ document.body.classList.remove('--fixed'); if(window.innerWidth - document.body.clientWidth){ document.body.style.paddingRight = ''; } } document.removeEventListener('keydown', this.keyEscape); if(!window.popUpers.length){ document.body.classList.remove('--fixed'); } } createEl(tag, className) { const el = document.createElement(tag); if(className){ el.classList.add(className) } return el; } }