UNPKG

3.23 kBJavaScriptView Raw
1import Vue from 'vue';
2import loadingVue from './loading.vue';
3import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom';
4import { PopupManager } from 'element-ui/src/utils/popup';
5import afterLeave from 'element-ui/src/utils/after-leave';
6import merge from 'element-ui/src/utils/merge';
7
8const LoadingConstructor = Vue.extend(loadingVue);
9
10const defaults = {
11 text: null,
12 fullscreen: true,
13 body: false,
14 lock: false,
15 customClass: ''
16};
17
18let fullscreenLoading;
19
20LoadingConstructor.prototype.originalPosition = '';
21LoadingConstructor.prototype.originalOverflow = '';
22
23LoadingConstructor.prototype.close = function() {
24 if (this.fullscreen) {
25 fullscreenLoading = undefined;
26 }
27 afterLeave(this, _ => {
28 const target = this.fullscreen || this.body
29 ? document.body
30 : this.target;
31 removeClass(target, 'el-loading-parent--relative');
32 removeClass(target, 'el-loading-parent--hidden');
33 if (this.$el && this.$el.parentNode) {
34 this.$el.parentNode.removeChild(this.$el);
35 }
36 this.$destroy();
37 }, 300);
38 this.visible = false;
39};
40
41const addStyle = (options, parent, instance) => {
42 let maskStyle = {};
43 if (options.fullscreen) {
44 instance.originalPosition = getStyle(document.body, 'position');
45 instance.originalOverflow = getStyle(document.body, 'overflow');
46 maskStyle.zIndex = PopupManager.nextZIndex();
47 } else if (options.body) {
48 instance.originalPosition = getStyle(document.body, 'position');
49 ['top', 'left'].forEach(property => {
50 let scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
51 maskStyle[property] = options.target.getBoundingClientRect()[property] +
52 document.body[scroll] +
53 document.documentElement[scroll] +
54 'px';
55 });
56 ['height', 'width'].forEach(property => {
57 maskStyle[property] = options.target.getBoundingClientRect()[property] + 'px';
58 });
59 } else {
60 instance.originalPosition = getStyle(parent, 'position');
61 }
62 Object.keys(maskStyle).forEach(property => {
63 instance.$el.style[property] = maskStyle[property];
64 });
65};
66
67const Loading = (options = {}) => {
68 if (Vue.prototype.$isServer) return;
69 options = merge({}, defaults, options);
70 if (typeof options.target === 'string') {
71 options.target = document.querySelector(options.target);
72 }
73 options.target = options.target || document.body;
74 if (options.target !== document.body) {
75 options.fullscreen = false;
76 } else {
77 options.body = true;
78 }
79 if (options.fullscreen && fullscreenLoading) {
80 return fullscreenLoading;
81 }
82
83 let parent = options.body ? document.body : options.target;
84 let instance = new LoadingConstructor({
85 el: document.createElement('div'),
86 data: options
87 });
88
89 addStyle(options, parent, instance);
90 if (instance.originalPosition !== 'absolute' && instance.originalPosition !== 'fixed') {
91 addClass(parent, 'el-loading-parent--relative');
92 }
93 if (options.fullscreen && options.lock) {
94 addClass(parent, 'el-loading-parent--hidden');
95 }
96 parent.appendChild(instance.$el);
97 Vue.nextTick(() => {
98 instance.visible = true;
99 });
100 if (options.fullscreen) {
101 fullscreenLoading = instance;
102 }
103 return instance;
104};
105
106export default Loading;