element/packages/loading/src/directive.js

119 lines
3.6 KiB
JavaScript
Raw Normal View History

2016-08-25 10:37:03 +00:00
import Spinner from './spinner';
2016-07-27 06:15:02 +00:00
exports.install = Vue => {
2016-08-29 11:01:42 +00:00
let toggleLoading = (el, binding) => {
if (binding.value) {
Vue.nextTick(() => {
if (binding.modifiers.fullscreen) {
el.originalPosition = document.body.style.position;
el.originalOverflow = document.body.style.overflow;
['top', 'right', 'bottom', 'left'].forEach(property => {
el.maskStyle[property] = '0';
});
el.maskStyle.position = 'fixed';
el.spinnerStyle.position = 'fixed';
insertDom(document.body, el, binding);
} else {
if (binding.modifiers.body) {
el.originalPosition = document.body.style.position;
['top', 'left'].forEach(property => {
let scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
el.maskStyle[property] = el.getBoundingClientRect()[property] + document.body[scroll] + document.documentElement[scroll] + 'px';
});
['height', 'width'].forEach(property => {
el.maskStyle[property] = el.getBoundingClientRect()[property] + 'px';
});
insertDom(document.body, el, binding);
} else {
el.originalPosition = el.style.position;
['top', 'right', 'bottom', 'left'].forEach(property => {
el.maskStyle[property] = '0';
});
insertDom(el, el, binding);
}
}
});
} else {
if (el.domVisible) {
el.mask.style.display = 'none';
el.spinner.style.display = 'none';
el.domVisible = false;
if (binding.modifiers.fullscreen) {
document.body.style.overflow = el.originalOverflow;
}
if (binding.modifiers.fullscreen || binding.modifiers.body) {
document.body.style.position = el.originalPosition;
} else {
el.style.position = el.originalPosition;
}
}
}
};
2016-08-12 07:49:47 +00:00
let insertDom = (parent, directive, binding) => {
2016-07-27 06:15:02 +00:00
if (!directive.domVisible) {
Object.keys(directive.maskStyle).forEach(property => {
directive.mask.style[property] = directive.maskStyle[property];
});
Object.keys(directive.spinnerStyle).forEach(property => {
directive.spinner.style[property] = directive.spinnerStyle[property];
});
if (directive.originalPosition !== 'absolute') {
parent.style.position = 'relative';
}
2016-08-12 07:49:47 +00:00
if (binding.modifiers.fullscreen) {
2016-07-27 06:15:02 +00:00
parent.style.overflow = 'hidden';
}
directive.mask.style.display = 'block';
directive.spinner.style.display = 'inline-block';
directive.domVisible = true;
parent.appendChild(directive.mask);
directive.mask.appendChild(directive.spinner);
directive.domInserted = true;
}
};
Vue.directive('loading', {
2016-08-29 11:01:42 +00:00
bind: function(el, binding) {
2016-08-12 07:49:47 +00:00
el.mask = document.createElement('div');
el.mask.className = 'el-loading-mask';
el.maskStyle = {
2016-07-27 06:15:02 +00:00
position: 'absolute',
zIndex: '10000',
2016-08-25 08:37:55 +00:00
backgroundColor: 'rgba(0, 0, 0, .65)',
2016-07-27 06:15:02 +00:00
margin: '0'
};
2016-08-25 10:37:03 +00:00
el.spinner = (new Spinner()).el;
2016-08-12 07:49:47 +00:00
el.spinnerStyle = {
2016-08-25 10:37:03 +00:00
position: 'absolute'
2016-07-27 06:15:02 +00:00
};
2016-08-29 11:01:42 +00:00
toggleLoading(el, binding);
2016-07-27 06:15:02 +00:00
},
2016-08-12 07:49:47 +00:00
update: function(el, binding) {
2016-08-29 11:01:42 +00:00
toggleLoading(el, binding);
2016-07-27 06:15:02 +00:00
},
2016-08-12 07:49:47 +00:00
unbind: function(el, binding) {
if (el.domInserted) {
if (binding.modifiers.fullscreen || binding.modifiers.body) {
document.body.removeChild(el.mask);
el.mask.removeChild(el.spinner);
2016-07-27 06:15:02 +00:00
} else {
2016-08-12 07:49:47 +00:00
el.removeChild(el.mask);
el.mask.removeChild(el.spinner);
2016-07-27 06:15:02 +00:00
}
}
}
});
};