项目原始demo,不改动
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
Este repositorio está archivado. Puede ver los archivos y clonarlo, pero no puede subir cambios o reportar incidencias ni pedir Pull Requests.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Components
  2. import VOverlay from '../../components/VOverlay'; // Utilities
  3. import { keyCodes, addOnceEventListener, addPassiveEventListener, getZIndex } from '../../util/helpers'; // Types
  4. import Vue from 'vue';
  5. /* @vue/component */
  6. export default Vue.extend().extend({
  7. name: 'overlayable',
  8. props: {
  9. hideOverlay: Boolean,
  10. overlayColor: String,
  11. overlayOpacity: [Number, String]
  12. },
  13. data() {
  14. return {
  15. overlay: null
  16. };
  17. },
  18. watch: {
  19. hideOverlay(value) {
  20. if (!this.isActive) return;
  21. if (value) this.removeOverlay();else this.genOverlay();
  22. }
  23. },
  24. beforeDestroy() {
  25. this.removeOverlay();
  26. },
  27. methods: {
  28. createOverlay() {
  29. const overlay = new VOverlay({
  30. propsData: {
  31. absolute: this.absolute,
  32. value: false,
  33. color: this.overlayColor,
  34. opacity: this.overlayOpacity
  35. }
  36. });
  37. overlay.$mount();
  38. const parent = this.absolute ? this.$el.parentNode : document.querySelector('[data-app]');
  39. parent && parent.insertBefore(overlay.$el, parent.firstChild);
  40. this.overlay = overlay;
  41. },
  42. genOverlay() {
  43. this.hideScroll();
  44. if (this.hideOverlay) return;
  45. if (!this.overlay) this.createOverlay();
  46. requestAnimationFrame(() => {
  47. if (!this.overlay) return;
  48. if (this.activeZIndex !== undefined) {
  49. this.overlay.zIndex = String(this.activeZIndex - 1);
  50. } else if (this.$el) {
  51. this.overlay.zIndex = getZIndex(this.$el);
  52. }
  53. });
  54. if (this.overlay) {
  55. this.overlay.value = true;
  56. }
  57. return true;
  58. },
  59. /** removeOverlay(false) will not restore the scollbar afterwards */
  60. removeOverlay(showScroll = true) {
  61. if (this.overlay) {
  62. addOnceEventListener(this.overlay.$el, 'transitionend', () => {
  63. if (!this.overlay || !this.overlay.$el || !this.overlay.$el.parentNode || this.overlay.value) return;
  64. this.overlay.$el.parentNode.removeChild(this.overlay.$el);
  65. this.overlay.$destroy();
  66. this.overlay = null;
  67. });
  68. this.overlay.value = false;
  69. }
  70. showScroll && this.showScroll();
  71. },
  72. scrollListener(e) {
  73. if (e.type === 'keydown') {
  74. if (['INPUT', 'TEXTAREA', 'SELECT'].includes(e.target.tagName) || // https://github.com/vuetifyjs/vuetify/issues/4715
  75. e.target.isContentEditable) return;
  76. const up = [keyCodes.up, keyCodes.pageup];
  77. const down = [keyCodes.down, keyCodes.pagedown];
  78. if (up.includes(e.keyCode)) {
  79. e.deltaY = -1;
  80. } else if (down.includes(e.keyCode)) {
  81. e.deltaY = 1;
  82. } else {
  83. return;
  84. }
  85. }
  86. if (e.target === this.overlay || e.type !== 'keydown' && e.target === document.body || this.checkPath(e)) e.preventDefault();
  87. },
  88. hasScrollbar(el) {
  89. if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
  90. const style = window.getComputedStyle(el);
  91. return ['auto', 'scroll'].includes(style.overflowY) && el.scrollHeight > el.clientHeight;
  92. },
  93. shouldScroll(el, delta) {
  94. if (el.scrollTop === 0 && delta < 0) return true;
  95. return el.scrollTop + el.clientHeight === el.scrollHeight && delta > 0;
  96. },
  97. isInside(el, parent) {
  98. if (el === parent) {
  99. return true;
  100. } else if (el === null || el === document.body) {
  101. return false;
  102. } else {
  103. return this.isInside(el.parentNode, parent);
  104. }
  105. },
  106. checkPath(e) {
  107. const path = e.path || this.composedPath(e);
  108. const delta = e.deltaY;
  109. if (e.type === 'keydown' && path[0] === document.body) {
  110. const dialog = this.$refs.dialog; // getSelection returns null in firefox in some edge cases, can be ignored
  111. const selected = window.getSelection().anchorNode;
  112. if (dialog && this.hasScrollbar(dialog) && this.isInside(selected, dialog)) {
  113. return this.shouldScroll(dialog, delta);
  114. }
  115. return true;
  116. }
  117. for (let index = 0; index < path.length; index++) {
  118. const el = path[index];
  119. if (el === document) return true;
  120. if (el === document.documentElement) return true;
  121. if (el === this.$refs.content) return true;
  122. if (this.hasScrollbar(el)) return this.shouldScroll(el, delta);
  123. }
  124. return true;
  125. },
  126. /**
  127. * Polyfill for Event.prototype.composedPath
  128. */
  129. composedPath(e) {
  130. if (e.composedPath) return e.composedPath();
  131. const path = [];
  132. let el = e.target;
  133. while (el) {
  134. path.push(el);
  135. if (el.tagName === 'HTML') {
  136. path.push(document);
  137. path.push(window);
  138. return path;
  139. }
  140. el = el.parentElement;
  141. }
  142. return path;
  143. },
  144. hideScroll() {
  145. if (this.$vuetify.breakpoint.smAndDown) {
  146. document.documentElement.classList.add('overflow-y-hidden');
  147. } else {
  148. addPassiveEventListener(window, 'wheel', this.scrollListener, {
  149. passive: false
  150. });
  151. window.addEventListener('keydown', this.scrollListener);
  152. }
  153. },
  154. showScroll() {
  155. document.documentElement.classList.remove('overflow-y-hidden');
  156. window.removeEventListener('wheel', this.scrollListener);
  157. window.removeEventListener('keydown', this.scrollListener);
  158. }
  159. }
  160. });
  161. //# sourceMappingURL=index.js.map