Blame view

node_modules/element-ui/packages/loading/src/directive.js 4.38 KB
2a09d1a4   liuqimichale   添加宜春 天水 宣化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  import Vue from 'vue';
  import Loading from './loading.vue';
  import { addClass, removeClass, getStyle } from 'element-ui/src/utils/dom';
  import { PopupManager } from 'element-ui/src/utils/popup';
  import afterLeave from 'element-ui/src/utils/after-leave';
  const Mask = Vue.extend(Loading);
  
  const loadingDirective = {};
  loadingDirective.install = Vue => {
    if (Vue.prototype.$isServer) return;
    const toggleLoading = (el, binding) => {
      if (binding.value) {
        Vue.nextTick(() => {
          if (binding.modifiers.fullscreen) {
            el.originalPosition = getStyle(document.body, 'position');
            el.originalOverflow = getStyle(document.body, 'overflow');
            el.maskStyle.zIndex = PopupManager.nextZIndex();
  
            addClass(el.mask, 'is-fullscreen');
            insertDom(document.body, el, binding);
          } else {
            removeClass(el.mask, 'is-fullscreen');
  
            if (binding.modifiers.body) {
              el.originalPosition = getStyle(document.body, 'position');
  
              ['top', 'left'].forEach(property => {
                const scroll = property === 'top' ? 'scrollTop' : 'scrollLeft';
                el.maskStyle[property] = el.getBoundingClientRect()[property] +
                  document.body[scroll] +
                  document.documentElement[scroll] -
                  parseInt(getStyle(document.body, `margin-${ property }`), 10) +
                  'px';
              });
              ['height', 'width'].forEach(property => {
                el.maskStyle[property] = el.getBoundingClientRect()[property] + 'px';
              });
  
              insertDom(document.body, el, binding);
            } else {
              el.originalPosition = getStyle(el, 'position');
              insertDom(el, el, binding);
            }
          }
        });
      } else {
        afterLeave(el.instance, _ => {
          el.domVisible = false;
          const target = binding.modifiers.fullscreen || binding.modifiers.body
            ? document.body
            : el;
          removeClass(target, 'el-loading-parent--relative');
          removeClass(target, 'el-loading-parent--hidden');
          el.instance.hiding = false;
        }, 300, true);
        el.instance.visible = false;
        el.instance.hiding = true;
      }
    };
    const insertDom = (parent, el, binding) => {
      if (!el.domVisible && getStyle(el, 'display') !== 'none' && getStyle(el, 'visibility') !== 'hidden') {
        Object.keys(el.maskStyle).forEach(property => {
          el.mask.style[property] = el.maskStyle[property];
        });
  
        if (el.originalPosition !== 'absolute' && el.originalPosition !== 'fixed') {
          addClass(parent, 'el-loading-parent--relative');
        }
        if (binding.modifiers.fullscreen && binding.modifiers.lock) {
          addClass(parent, 'el-loading-parent--hidden');
        }
        el.domVisible = true;
  
        parent.appendChild(el.mask);
        Vue.nextTick(() => {
          if (el.instance.hiding) {
            el.instance.$emit('after-leave');
          } else {
            el.instance.visible = true;
          }
        });
        el.domInserted = true;
      }
    };
  
    Vue.directive('loading', {
      bind: function(el, binding, vnode) {
        const textExr = el.getAttribute('element-loading-text');
        const spinnerExr = el.getAttribute('element-loading-spinner');
        const backgroundExr = el.getAttribute('element-loading-background');
        const customClassExr = el.getAttribute('element-loading-custom-class');
        const vm = vnode.context;
        const mask = new Mask({
          el: document.createElement('div'),
          data: {
            text: vm && vm[textExr] || textExr,
            spinner: vm && vm[spinnerExr] || spinnerExr,
            background: vm && vm[backgroundExr] || backgroundExr,
            customClass: vm && vm[customClassExr] || customClassExr,
            fullscreen: !!binding.modifiers.fullscreen
          }
        });
        el.instance = mask;
        el.mask = mask.$el;
        el.maskStyle = {};
  
        binding.value && toggleLoading(el, binding);
      },
  
      update: function(el, binding) {
        el.instance.setText(el.getAttribute('element-loading-text'));
        if (binding.oldValue !== binding.value) {
          toggleLoading(el, binding);
        }
      },
  
      unbind: function(el, binding) {
        if (el.domInserted) {
          el.mask &&
          el.mask.parentNode &&
          el.mask.parentNode.removeChild(el.mask);
          toggleLoading(el, { value: false, modifiers: binding.modifiers });
        }
      }
    });
  };
  
  export default loadingDirective;