import { dom, uuid } from 'utils'; const isIdSelector = dom.isIdSelector; var defaultConfig = { containerCss: 'loading-container', type: 'page', // loading类型 page|modal,默认page类型 target: null, // 要插入的目标dom,不指定默认为body fullscreen: true, // 是否全屏 background: null, // 背景颜色 backdrop: true, // 是否需要蒙版 lock: false, // 锁定滚动 text: null, spinner: null, autoMiddle: true, onlyOne: true, // 是否唯一,是则为单例模式 destroyed: null, // 生命周期-销毁 duration: 15000, // 持续时间,为0不做限制 }; var Loading = function (config) { this.config = config; this.init(config); this.open(config); } // == 初始化,加载laoding容器 Loading.prototype.init = function (config) { if(!config.target) { this.body = document.body; }else if(typeof config.target == 'string') { var isId = isIdSelector(config.target); this.body = isId ? document.getElementById(config.target.replace('#', '')) : document.querySelector(config.target); }else if(typeof config.target == 'object' && config.target instanceof HTMLElement){ this.body = config.target; } // 生成loading容器(背景) if(config.backdrop){ var id = uuid(); var containerCss = config.containerCss; var color = config.background; var uuidCss = containerCss + '-' + id; var containerElem = this.getContainerElem(containerCss, uuidCss, color); this.body.insertAdjacentHTML('beforeend',containerElem); this.container = this.body.querySelector('.' + uuidCss); }else{ this.container = this.body; } } // == 获取容器 Loading.prototype.getContainerElem = function (css, uuidCss, color) { if(color){ return '
'; }else{ return '
'; } } // == 打开loading Loading.prototype.open = function (config) { var self = this; // 添加配置css this.container.classList.add('loading-type-' + config.type); if(config.fullscreen) { if(config.target) this.body.classList.add('loading-relative'); this.container.classList.add('loading-fullscreen'); } // 解析模板 var template = this.parseTemplate(config); this.container.insertAdjacentHTML('beforeend',template); this.element = this.container.childNodes[this.container.childNodes.length - 1]; // 自动垂直居中 if(config.autoMiddle) this.autoMiddle(this.element); // 显示loading this.show(config); if(config.lock) this.disableScroll(); // 指定持续时间则定时关闭 if(config.duration){ this.closeTimer = setTimeout(function () { self.close(); }, config.duration); } } // == 显示loading Loading.prototype.show = function (config) { var self = this; if(config.backdrop){ this.container.classList.add('active'); this.container.classList.add('in'); setTimeout(function () { if(self.container) self.container.classList.remove('in'); },300); } } // == 关闭loading Loading.prototype.close = function (callback,immediately) { var self = this; if(!this.container) return; if(this.closeTimer) clearTimeout(this.closeTimer); this.hide(function () { self.destroy(); if(self.config.destroyed) self.config.destroyed(this); if(self.config.lock) self.enableScroll(); if(callback) callback(); },immediately); } // == 隐藏loading Loading.prototype.hide = function (callback,immediately) { var self = this; if(this.config.backdrop){ if(immediately){ if(this.container) this.container.classList.remove('active'); callback(); }else{ this.container.classList.add('out'); setTimeout(function () { if(self.container) self.container.classList.remove('active'); if(self.container) self.container.classList.remove('out'); callback(); },200); } } } // == 销毁loading Loading.prototype.destroy = function () { if(this.container) this.body.removeChild(this.container); this.container = null; this.element = null; } // 自动居中 Loading.prototype.autoMiddle = function (elem) { var width = elem.offsetWidth; var allWidth = this.body.offsetWidth; // 水平居中 if(allWidth > width){ elem.style.marginLeft = '-' + width/2 + 'px'; } // 垂直居中 var height = elem.offsetHeight; elem.style.marginTop = '-' + height/2 + 'px'; } // 解析模板 Loading.prototype.parseTemplate = function (config) { var text = config.text; var spinnerHtml = config.spinner || '' + '' + ''; var textHtml = text ? '
' + text + '
' : ''; return '
' + spinnerHtml + textHtml + '
'; } Loading.prototype.disableScroll = function () { this.body.classList.add('loading-disable-scroll'); } Loading.prototype.enableScroll = function () { this.body.classList.remove('loading-disable-scroll'); } // == 解析配置 function parseConfig(text, config) { if(text && typeof text === 'object'){ config = text; }else{ // 第二个参数为字符,则作为type参数处理 if(typeof config === 'string'){ var type = config; config = { type: type }; }else{ config = config || {}; } config.text = text || config.text || defaultConfig.text; } config = Object.assign({}, defaultConfig, config); return config; } var loadingInstance; // loading实例,单例模式用 export const create = function (text?, config?) { config = parseConfig(text, config); if(config.onlyOne){ if(!loadingInstance){ var instance = new Loading(config); loadingInstance = Object.assign({}, instance); loadingInstance.close = function (cb, immediately) { loadingInstance = null; instance.close(cb, immediately); } } return loadingInstance; }else{ return new Loading(config); } }