directive.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import Spinner from './spinner';
  2. exports.install = Vue => {
  3. let toggleLoading = (el, binding) => {
  4. if (binding.value) {
  5. Vue.nextTick(() => {
  6. if (binding.modifiers.fullscreen) {
  7. el.originalPosition = document.body.style.position;
  8. el.originalOverflow = document.body.style.overflow;
  9. ['top', 'right', 'bottom', 'left'].forEach(property => {
  10. el.maskStyle[property] = '0';
  11. });
  12. el.maskStyle.position = 'fixed';
  13. el.spinnerStyle.position = 'fixed';
  14. insertDom(document.body, el, binding);
  15. } else {
  16. if (binding.modifiers.body) {
  17. el.originalPosition = document.body.style.position;
  18. ['top', 'left'].forEach(property => {
  19. let scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
  20. el.maskStyle[property] = el.getBoundingClientRect()[property] + document.body[scroll] + document.documentElement[scroll] + 'px';
  21. });
  22. ['height', 'width'].forEach(property => {
  23. el.maskStyle[property] = el.getBoundingClientRect()[property] + 'px';
  24. });
  25. insertDom(document.body, el, binding);
  26. } else {
  27. el.originalPosition = el.style.position;
  28. ['top', 'right', 'bottom', 'left'].forEach(property => {
  29. el.maskStyle[property] = '0';
  30. });
  31. insertDom(el, el, binding);
  32. }
  33. }
  34. });
  35. } else {
  36. if (el.domVisible) {
  37. el.mask.style.display = 'none';
  38. el.spinner.style.display = 'none';
  39. el.domVisible = false;
  40. if (binding.modifiers.fullscreen) {
  41. document.body.style.overflow = el.originalOverflow;
  42. }
  43. if (binding.modifiers.fullscreen || binding.modifiers.body) {
  44. document.body.style.position = el.originalPosition;
  45. } else {
  46. el.style.position = el.originalPosition;
  47. }
  48. }
  49. }
  50. };
  51. let insertDom = (parent, directive, binding) => {
  52. if (!directive.domVisible) {
  53. Object.keys(directive.maskStyle).forEach(property => {
  54. directive.mask.style[property] = directive.maskStyle[property];
  55. });
  56. Object.keys(directive.spinnerStyle).forEach(property => {
  57. directive.spinner.style[property] = directive.spinnerStyle[property];
  58. });
  59. if (directive.originalPosition !== 'absolute') {
  60. parent.style.position = 'relative';
  61. }
  62. if (binding.modifiers.fullscreen && binding.modifiers.lock) {
  63. parent.style.overflow = 'hidden';
  64. }
  65. directive.mask.style.display = 'block';
  66. directive.spinner.style.display = 'inline-block';
  67. directive.domVisible = true;
  68. parent.appendChild(directive.mask);
  69. directive.mask.appendChild(directive.spinner);
  70. directive.domInserted = true;
  71. }
  72. };
  73. Vue.directive('loading', {
  74. bind: function(el, binding) {
  75. el.mask = document.createElement('div');
  76. el.mask.className = 'el-loading-mask';
  77. el.maskStyle = {
  78. position: 'absolute',
  79. zIndex: '10000',
  80. backgroundColor: 'rgba(0, 0, 0, .65)',
  81. margin: '0'
  82. };
  83. el.spinner = (new Spinner()).el;
  84. el.spinnerStyle = {
  85. position: 'absolute'
  86. };
  87. toggleLoading(el, binding);
  88. },
  89. update: function(el, binding) {
  90. toggleLoading(el, binding);
  91. },
  92. unbind: function(el, binding) {
  93. if (el.domInserted) {
  94. if (binding.modifiers.fullscreen || binding.modifiers.body) {
  95. document.body.removeChild(el.mask);
  96. el.mask.removeChild(el.spinner);
  97. } else {
  98. el.removeChild(el.mask);
  99. el.mask.removeChild(el.spinner);
  100. }
  101. }
  102. }
  103. });
  104. };