element/packages/loading/src/directive.js

112 lines
3.5 KiB
JavaScript
Raw Normal View History

2017-06-30 14:49:20 +00:00
import Vue from 'vue';
import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom';
let Mask = Vue.extend(require('./loading.vue'));
2016-07-27 06:15:02 +00:00
exports.install = Vue => {
2017-06-30 14:49:20 +00:00
if (Vue.prototype.$isServer) return;
2016-08-29 11:01:42 +00:00
let toggleLoading = (el, binding) => {
if (binding.value) {
Vue.nextTick(() => {
if (binding.modifiers.fullscreen) {
2017-08-18 08:58:18 +00:00
el.originalPosition = getStyle(document.body, 'position');
el.originalOverflow = getStyle(document.body, 'overflow');
2016-08-29 11:01:42 +00:00
2017-06-30 14:49:20 +00:00
addClass(el.mask, 'is-fullscreen');
insertDom(document.body, el, binding);
2016-08-29 11:01:42 +00:00
} else {
2017-06-30 14:49:20 +00:00
removeClass(el.mask, 'is-fullscreen');
2016-08-29 11:01:42 +00:00
if (binding.modifiers.body) {
2017-08-18 08:58:18 +00:00
el.originalPosition = getStyle(document.body, 'position');
2016-08-29 11:01:42 +00:00
['top', 'left'].forEach(property => {
2017-06-30 14:49:20 +00:00
let scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
el.maskStyle[property] = el.getBoundingClientRect()[property] + document.body[scroll] + document.documentElement[scroll] + 'px';
2016-08-29 11:01:42 +00:00
});
['height', 'width'].forEach(property => {
2017-06-30 14:49:20 +00:00
el.maskStyle[property] = el.getBoundingClientRect()[property] + 'px';
});
2016-08-29 11:01:42 +00:00
2017-06-30 14:49:20 +00:00
insertDom(document.body, el, binding);
2016-08-29 11:01:42 +00:00
} else {
2017-08-18 08:58:18 +00:00
el.originalPosition = getStyle(el, 'position');
2017-06-30 14:49:20 +00:00
insertDom(el, el, binding);
2016-08-29 11:01:42 +00:00
}
}
2017-06-30 14:49:20 +00:00
});
2016-08-29 11:01:42 +00:00
} else {
if (el.domVisible) {
2017-01-13 11:52:26 +00:00
el.instance.$on('after-leave', _ => {
2017-06-30 14:49:20 +00:00
el.domVisible = false;
2017-01-13 07:31:05 +00:00
if (binding.modifiers.fullscreen && el.originalOverflow !== 'hidden') {
2017-06-30 14:49:20 +00:00
document.body.style.overflow = el.originalOverflow;
2017-01-13 07:31:05 +00:00
}
if (binding.modifiers.fullscreen || binding.modifiers.body) {
2017-06-30 14:49:20 +00:00
document.body.style.position = el.originalPosition;
2017-01-13 07:31:05 +00:00
} else {
2017-06-30 14:49:20 +00:00
el.style.position = el.originalPosition;
2017-01-13 07:31:05 +00:00
}
2017-06-30 14:49:20 +00:00
});
el.instance.visible = false;
2016-08-29 11:01:42 +00:00
}
}
2017-06-30 14:49:20 +00:00
};
2017-01-13 07:31:05 +00:00
let insertDom = (parent, el, binding) => {
2017-06-30 14:25:16 +00:00
if (!el.domVisible && getStyle(el, 'display') !== 'none' && getStyle(el, 'visibility') !== 'hidden') {
2017-01-13 07:31:05 +00:00
Object.keys(el.maskStyle).forEach(property => {
2017-06-30 14:49:20 +00:00
el.mask.style[property] = el.maskStyle[property];
});
2016-07-27 06:15:02 +00:00
2017-08-18 08:58:18 +00:00
if (el.originalPosition !== 'absolute' && el.originalPosition !== 'fixed') {
2017-06-30 14:49:20 +00:00
parent.style.position = 'relative';
2016-07-27 06:15:02 +00:00
}
2016-10-13 12:05:42 +00:00
if (binding.modifiers.fullscreen && binding.modifiers.lock) {
2017-06-30 14:49:20 +00:00
parent.style.overflow = 'hidden';
2016-07-27 06:15:02 +00:00
}
2017-06-30 14:49:20 +00:00
el.domVisible = true;
2016-07-27 06:15:02 +00:00
2017-06-30 14:49:20 +00:00
parent.appendChild(el.mask);
2017-01-13 07:31:05 +00:00
Vue.nextTick(() => {
2017-06-30 14:49:20 +00:00
el.instance.visible = true;
});
el.domInserted = true;
2016-07-27 06:15:02 +00:00
}
2017-06-30 14:49:20 +00:00
};
2016-07-27 06:15:02 +00:00
Vue.directive('loading', {
2017-06-30 14:49:20 +00:00
bind: function(el, binding) {
2016-11-15 12:29:33 +00:00
let mask = new Mask({
el: document.createElement('div'),
data: {
text: el.getAttribute('element-loading-text'),
2016-11-15 12:29:33 +00:00
fullscreen: !!binding.modifiers.fullscreen
}
2017-06-30 14:49:20 +00:00
});
el.instance = mask;
el.mask = mask.$el;
el.maskStyle = {};
2016-11-15 12:29:33 +00:00
2017-06-30 14:49:20 +00:00
toggleLoading(el, binding);
2016-07-27 06:15:02 +00:00
},
2017-06-30 14:49:20 +00:00
update: function(el, binding) {
el.instance.setText(el.getAttribute('element-loading-text'));
if (binding.oldValue !== binding.value) {
2017-06-30 14:49:20 +00:00
toggleLoading(el, binding);
}
2016-07-27 06:15:02 +00:00
},
2017-06-30 14:49:20 +00:00
unbind: function(el, binding) {
2016-08-12 07:49:47 +00:00
if (el.domInserted) {
if (binding.modifiers.fullscreen || binding.modifiers.body) {
2017-06-30 14:49:20 +00:00
document.body.removeChild(el.mask);
2016-07-27 06:15:02 +00:00
} else {
el.mask &&
el.mask.parentNode &&
2017-06-30 14:49:20 +00:00
el.mask.parentNode.removeChild(el.mask);
2016-07-27 06:15:02 +00:00
}
}
}
2017-06-30 14:49:20 +00:00
});
};