element/packages/loading/src/index.js

109 lines
3.0 KiB
JavaScript
Raw Normal View History

2016-11-15 12:29:33 +00:00
import Vue from 'vue';
import loadingVue from './loading.vue';
import merge from 'element-ui/src/utils/merge';
const LoadingConstructor = Vue.extend(loadingVue);
const defaults = {
text: null,
fullscreen: true,
body: false,
lock: false,
customClass: ''
};
let fullscreenLoading;
LoadingConstructor.prototype.originalPosition = '';
LoadingConstructor.prototype.originalOverflow = '';
2016-11-15 12:29:33 +00:00
2017-01-13 07:31:05 +00:00
const destroyElement = function() {
this.$el.removeEventListener('transitionend', destroyElement);
this.$el &&
this.$el.parentNode &&
this.$el.parentNode.removeChild(this.$el);
this.$destroy();
};
2016-11-15 12:29:33 +00:00
LoadingConstructor.prototype.close = function() {
if (this.fullscreen && this.originalOverflow !== 'hidden') {
document.body.style.overflow = this.originalOverflow;
2016-11-15 12:29:33 +00:00
}
if (this.fullscreen || this.body) {
document.body.style.position = this.originalPosition;
2016-11-15 12:29:33 +00:00
} else {
this.target.style.position = this.originalPosition;
}
if (this.fullscreen) {
fullscreenLoading = undefined;
2016-11-15 12:29:33 +00:00
}
2017-01-13 07:31:05 +00:00
this.$el.addEventListener('transitionend', destroyElement.bind(this));
this.visible = false;
2016-11-15 12:29:33 +00:00
};
const addStyle = (options, parent, instance) => {
2016-11-15 12:29:33 +00:00
let maskStyle = {};
if (options.fullscreen) {
instance.originalPosition = document.body.style.position;
instance.originalOverflow = document.body.style.overflow;
2016-11-15 12:29:33 +00:00
} else if (options.body) {
instance.originalPosition = document.body.style.position;
2016-11-15 12:29:33 +00:00
['top', 'left'].forEach(property => {
let scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
maskStyle[property] = options.target.getBoundingClientRect()[property] +
document.body[scroll] +
document.documentElement[scroll] +
'px';
});
['height', 'width'].forEach(property => {
maskStyle[property] = options.target.getBoundingClientRect()[property] + 'px';
});
} else {
instance.originalPosition = parent.style.position;
2016-11-15 12:29:33 +00:00
}
Object.keys(maskStyle).forEach(property => {
instance.$el.style[property] = maskStyle[property];
2016-11-15 12:29:33 +00:00
});
};
const Loading = (options = {}) => {
2016-12-26 02:45:20 +00:00
if (Vue.prototype.$isServer) return;
2016-11-15 12:29:33 +00:00
options = merge({}, defaults, options);
if (typeof options.target === 'string') {
options.target = document.querySelector(options.target);
}
options.target = options.target || document.body;
if (options.target !== document.body) {
options.fullscreen = false;
} else {
options.body = true;
}
if (options.fullscreen && fullscreenLoading) {
return fullscreenLoading;
}
2016-11-15 12:29:33 +00:00
let parent = options.body ? document.body : options.target;
let instance = new LoadingConstructor({
el: document.createElement('div'),
data: options
});
addStyle(options, parent, instance);
if (instance.originalPosition !== 'absolute') {
2016-11-15 12:29:33 +00:00
parent.style.position = 'relative';
}
if (options.fullscreen && options.lock) {
parent.style.overflow = 'hidden';
}
parent.appendChild(instance.$el);
2017-01-13 07:31:05 +00:00
Vue.nextTick(() => {
instance.visible = true;
});
if (options.fullscreen) {
fullscreenLoading = instance;
}
2016-11-15 12:29:33 +00:00
return instance;
};
export default Loading;