index.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var vue = require('vue');
  4. var shared = require('@vue/shared');
  5. var lodashUnified = require('lodash-unified');
  6. require('../../../utils/index.js');
  7. var position = require('../../../utils/dom/position.js');
  8. var error = require('../../../utils/error.js');
  9. var scroll = require('../../../utils/dom/scroll.js');
  10. const SCOPE = "ElInfiniteScroll";
  11. const CHECK_INTERVAL = 50;
  12. const DEFAULT_DELAY = 200;
  13. const DEFAULT_DISTANCE = 0;
  14. const attributes = {
  15. delay: {
  16. type: Number,
  17. default: DEFAULT_DELAY
  18. },
  19. distance: {
  20. type: Number,
  21. default: DEFAULT_DISTANCE
  22. },
  23. disabled: {
  24. type: Boolean,
  25. default: false
  26. },
  27. immediate: {
  28. type: Boolean,
  29. default: true
  30. }
  31. };
  32. const getScrollOptions = (el, instance) => {
  33. return Object.entries(attributes).reduce((acm, [name, option]) => {
  34. var _a, _b;
  35. const { type, default: defaultValue } = option;
  36. const attrVal = el.getAttribute(`infinite-scroll-${name}`);
  37. let value = (_b = (_a = instance[attrVal]) != null ? _a : attrVal) != null ? _b : defaultValue;
  38. value = value === "false" ? false : value;
  39. value = type(value);
  40. acm[name] = Number.isNaN(value) ? defaultValue : value;
  41. return acm;
  42. }, {});
  43. };
  44. const destroyObserver = (el) => {
  45. const { observer } = el[SCOPE];
  46. if (observer) {
  47. observer.disconnect();
  48. delete el[SCOPE].observer;
  49. }
  50. };
  51. const handleScroll = (el, cb) => {
  52. const { container, containerEl, instance, observer, lastScrollTop } = el[SCOPE];
  53. const { disabled, distance } = getScrollOptions(el, instance);
  54. const { clientHeight, scrollHeight, scrollTop } = containerEl;
  55. const delta = scrollTop - lastScrollTop;
  56. el[SCOPE].lastScrollTop = scrollTop;
  57. if (observer || disabled || delta < 0)
  58. return;
  59. let shouldTrigger = false;
  60. if (container === el) {
  61. shouldTrigger = scrollHeight - (clientHeight + scrollTop) <= distance;
  62. } else {
  63. const { clientTop, scrollHeight: height } = el;
  64. const offsetTop = position.getOffsetTopDistance(el, containerEl);
  65. shouldTrigger = scrollTop + clientHeight >= offsetTop + clientTop + height - distance;
  66. }
  67. if (shouldTrigger) {
  68. cb.call(instance);
  69. }
  70. };
  71. function checkFull(el, cb) {
  72. const { containerEl, instance } = el[SCOPE];
  73. const { disabled } = getScrollOptions(el, instance);
  74. if (disabled || containerEl.clientHeight === 0)
  75. return;
  76. if (containerEl.scrollHeight <= containerEl.clientHeight) {
  77. cb.call(instance);
  78. } else {
  79. destroyObserver(el);
  80. }
  81. }
  82. const InfiniteScroll = {
  83. async mounted(el, binding) {
  84. const { instance, value: cb } = binding;
  85. if (!shared.isFunction(cb)) {
  86. error.throwError(SCOPE, "'v-infinite-scroll' binding value must be a function");
  87. }
  88. await vue.nextTick();
  89. const { delay, immediate } = getScrollOptions(el, instance);
  90. const container = scroll.getScrollContainer(el, true);
  91. const containerEl = container === window ? document.documentElement : container;
  92. const onScroll = lodashUnified.throttle(handleScroll.bind(null, el, cb), delay);
  93. if (!container)
  94. return;
  95. el[SCOPE] = {
  96. instance,
  97. container,
  98. containerEl,
  99. delay,
  100. cb,
  101. onScroll,
  102. lastScrollTop: containerEl.scrollTop
  103. };
  104. if (immediate) {
  105. const observer = new MutationObserver(lodashUnified.throttle(checkFull.bind(null, el, cb), CHECK_INTERVAL));
  106. el[SCOPE].observer = observer;
  107. observer.observe(el, { childList: true, subtree: true });
  108. checkFull(el, cb);
  109. }
  110. container.addEventListener("scroll", onScroll);
  111. },
  112. unmounted(el) {
  113. const { container, onScroll } = el[SCOPE];
  114. container == null ? void 0 : container.removeEventListener("scroll", onScroll);
  115. destroyObserver(el);
  116. },
  117. async updated(el) {
  118. if (!el[SCOPE]) {
  119. await vue.nextTick();
  120. }
  121. const { containerEl, cb, observer } = el[SCOPE];
  122. if (containerEl.clientHeight && observer) {
  123. checkFull(el, cb);
  124. }
  125. }
  126. };
  127. exports.CHECK_INTERVAL = CHECK_INTERVAL;
  128. exports.DEFAULT_DELAY = DEFAULT_DELAY;
  129. exports.DEFAULT_DISTANCE = DEFAULT_DISTANCE;
  130. exports.SCOPE = SCOPE;
  131. exports["default"] = InfiniteScroll;
  132. //# sourceMappingURL=index.js.map