UNPKG

lu2

Version:

Simple and flexible UI component library based on native HTML and JavaScript

254 lines (226 loc) 8.35 kB
/** * @Loading.js * @author zhangxinxu * @version * @Created: 15-06-23 * @Log: 2017-09-19 loading类名的添加基于标签,而非类名 */ /* global module */ (function (global, factory) { if (typeof exports === 'object' && typeof module !== 'undefined') { module.exports = factory(); } else if (typeof define === 'function' && (define.amd || define.cmd)) { define(factory); } else { global.Loading = factory(); } // eslint-disable-next-line }((typeof global !== 'undefined') ? global // eslint-disable-next-line : ((typeof window !== 'undefined') ? window : ((typeof self !== 'undefined') ? self : this)), function () { var LOADING = 'loading'; // 样式类名统一处理 var CL = { add: function () { return ['ui', LOADING].concat([].slice.call(arguments)).join('-'); }, toString: function () { return 'ui-' + LOADING; } }; /** * 给HTML元素扩展一个loading属性 * 经测试,不会和IMG和IFRAME原生loading属性冲突 * 是否正在loading:element.loading * 设置元素loading:element.loading = true; * 取消loading效果:element.loading = false; */ Object.defineProperty(HTMLElement.prototype, 'loading', { configurable: true, enumerable: true, writeable: true, get: function () { return !!(this.classList.contains(CL) || this.classList.contains(LOADING) || this.matches(CL)); }, set: function (flag) { var action = 'remove'; if (flag) { action = 'add'; if (this.loading) { return flag; } } if (this.classList.contains(CL.toString().replace(LOADING, 'button'))) { this.classList[action](LOADING); } else { this.classList[action](CL); // IE9支持旋转 if (typeof funRunRotate == 'function') { funRunRotate(this); } } // Aria无障碍设置 this.setAttribute('aria-busy', !!flag); if (flag && this.innerHTML.trim() == '') { this.setAttribute('aria-label', '正在加载中'); } else { this.removeAttribute('aria-label'); } } }); /** * IE9浏览器动画支持 */ if (typeof window.getComputedStyle(document.head).transition == 'undefined') { var funRunRotate = function (eleLoading) { if (!eleLoading) { return; } // 方便控制旋转进行的loading图形 var eleLoadingBefore; if (eleLoading.loading == true) { if (!eleLoading.getAttribute('spin')) { eleLoadingBefore = document.createElement('i'); eleLoadingBefore.className = CL.add('before'); // 插入到前面 eleLoading.insertAdjacentElement('afterbegin', eleLoadingBefore); // 本身设置标志量 eleLoading.setAttribute('spin', ''); // 清除动画定时 clearInterval(eleLoading.timerLoading); // 开始旋转 var numStep = 16; eleLoading.timerLoading = setInterval(function () { var numRotate = eleLoading.rotate || 0; numRotate += 360 / numStep; if (numRotate > 360) { numRotate = numRotate - 360; } eleLoading.rotate = numRotate; // 设置transform旋转 eleLoadingBefore.style.msTransform = 'rotate(' + numRotate + 'deg)'; }, 1000 / numStep); } } else if (eleLoading.loading === false) { eleLoading.removeAttribute('spin'); eleLoadingBefore = eleLoading.querySelector('.' + CL.add('before')); // 节点移除 if (eleLoadingBefore) { eleLoadingBefore.remove(); } // 清除动画定时 clearInterval(eleLoading.timerLoading); } }; window.addEventListener('DOMContentLoaded', function () { document.querySelectorAll(CL).forEach(funRunRotate); }); document.body.addEventListener('DOMNodeInserted', function (event) { if (!event.target || event.target.nodeType != 1) { return; } // 插入节点 if (event.target.matches(CL)) { funRunRotate(event.target); } }); } /** * 为了暴露方法一致 * 实际开发多用不到Loading实例方法 */ var Loading = function (element, options) { var defaults = { // 其他参数attributes observer: 'childList', size: 2 }; if (typeof element == 'string') { element = document.querySelector(element); } if (!element) { return this; } var eleTarget = element; var objParams = Object.assign({}, defaults, options || {}); // 若干参数暴露 this.params = objParams; this.element = { target: element }; if (!eleTarget.data) { eleTarget.data = {}; } // 元素上存储loading实例 eleTarget.data.loading = this; // loading显示 this.show(); }; /** * loading效果的显示 * @return {[type]} [description] */ Loading.prototype.show = function () { var objParams = this.params; var eleTarget = this.element.target; if (objParams.observer == 'attributes') { eleTarget.loading = true; eleTarget.setAttribute('size', objParams.size); // 更新标志量 this.loading = true; this.display = true; } else if (objParams.observer == 'childList') { var strPosition = window.getComputedStyle(eleTarget).position; if (strPosition == 'static') { // 记住初始position属性值 if (eleTarget.style && eleTarget.style.position) { this.position = 'static-inline'; } else { this.position = 'static-computed'; } // 设置position为相对定位 // 方便loading图形居中显示 eleTarget.style.position = 'relative'; } else { this.position = ''; } eleTarget.initHTML = eleTarget.innerHTML; eleTarget.innerHTML = '<' + CL + ' size="' + objParams.size + ' align="center"></' + CL + '>'; // 更新标志量 this.loading = true; this.display = true; } }; /** * loading效果的取消 * @return {[type]} [description] */ Loading.prototype.hide = function () { var objParams = this.params; var eleTarget = this.element.target; if (objParams.observer == 'attributes') { eleTarget.loading = false; // 更新标志量 this.loading = false; this.display = false; } else if (objParams.observer == 'childList') { var strPosition = this.position; if (strPosition == 'static-inline') { eleTarget.style.position = 'static'; } else if (strPosition == 'static-computed') { eleTarget.style.position = ''; } // 移除<ui-loading>元素 if (typeof eleTarget.initHTML == 'string') { eleTarget.innerHTML = eleTarget.initHTML; } else if (eleTarget.querySelector(CL)) { eleTarget.querySelector(CL).remove(); } // 更新标志量 this.loading = false; this.display = false; } }; return Loading; }));