You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.0 KiB
130 lines
4.0 KiB
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
var vue = require('vue');
|
|
var shared = require('@vue/shared');
|
|
var throttle = require('lodash/throttle');
|
|
var dom = require('../../../utils/dom.js');
|
|
var error = require('../../../utils/error.js');
|
|
|
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
|
|
var throttle__default = /*#__PURE__*/_interopDefaultLegacy(throttle);
|
|
|
|
const SCOPE = "ElInfiniteScroll";
|
|
const CHECK_INTERVAL = 50;
|
|
const DEFAULT_DELAY = 200;
|
|
const DEFAULT_DISTANCE = 0;
|
|
const attributes = {
|
|
delay: {
|
|
type: Number,
|
|
default: DEFAULT_DELAY
|
|
},
|
|
distance: {
|
|
type: Number,
|
|
default: DEFAULT_DISTANCE
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
immediate: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
};
|
|
const getScrollOptions = (el, instance) => {
|
|
return Object.entries(attributes).reduce((acm, [name, option]) => {
|
|
var _a, _b;
|
|
const { type, default: defaultValue } = option;
|
|
const attrVal = el.getAttribute(`infinite-scroll-${name}`);
|
|
let value = (_b = (_a = instance[attrVal]) != null ? _a : attrVal) != null ? _b : defaultValue;
|
|
value = value === "false" ? false : value;
|
|
value = type(value);
|
|
acm[name] = Number.isNaN(value) ? defaultValue : value;
|
|
return acm;
|
|
}, {});
|
|
};
|
|
const destroyObserver = (el) => {
|
|
const { observer } = el[SCOPE];
|
|
if (observer) {
|
|
observer.disconnect();
|
|
delete el[SCOPE].observer;
|
|
}
|
|
};
|
|
const handleScroll = (el, cb) => {
|
|
const { container, containerEl, instance, observer, lastScrollTop } = el[SCOPE];
|
|
const { disabled, distance } = getScrollOptions(el, instance);
|
|
const { clientHeight, scrollHeight, scrollTop } = containerEl;
|
|
const delta = scrollTop - lastScrollTop;
|
|
el[SCOPE].lastScrollTop = scrollTop;
|
|
if (observer || disabled || delta < 0)
|
|
return;
|
|
let shouldTrigger = false;
|
|
if (container === el) {
|
|
shouldTrigger = scrollHeight - (clientHeight + scrollTop) <= distance;
|
|
} else {
|
|
const { clientTop, scrollHeight: height } = el;
|
|
const offsetTop = dom.getOffsetTopDistance(el, containerEl);
|
|
shouldTrigger = scrollTop + clientHeight >= offsetTop + clientTop + height - distance;
|
|
}
|
|
if (shouldTrigger) {
|
|
cb.call(instance);
|
|
}
|
|
};
|
|
function checkFull(el, cb) {
|
|
const { containerEl, instance } = el[SCOPE];
|
|
const { disabled } = getScrollOptions(el, instance);
|
|
if (disabled)
|
|
return;
|
|
if (containerEl.scrollHeight <= containerEl.clientHeight) {
|
|
cb.call(instance);
|
|
} else {
|
|
destroyObserver(el);
|
|
}
|
|
}
|
|
const InfiniteScroll = {
|
|
async mounted(el, binding) {
|
|
const { instance, value: cb } = binding;
|
|
if (!shared.isFunction(cb)) {
|
|
error.throwError(SCOPE, "'v-infinite-scroll' binding value must be a function");
|
|
}
|
|
await vue.nextTick();
|
|
const { delay, immediate } = getScrollOptions(el, instance);
|
|
const container = dom.getScrollContainer(el, true);
|
|
const containerEl = container === window ? document.documentElement : container;
|
|
const onScroll = throttle__default["default"](handleScroll.bind(null, el, cb), delay);
|
|
if (!container)
|
|
return;
|
|
el[SCOPE] = {
|
|
instance,
|
|
container,
|
|
containerEl,
|
|
delay,
|
|
cb,
|
|
onScroll,
|
|
lastScrollTop: containerEl.scrollTop
|
|
};
|
|
if (immediate) {
|
|
const observer = new MutationObserver(throttle__default["default"](checkFull.bind(null, el, cb), CHECK_INTERVAL));
|
|
el[SCOPE].observer = observer;
|
|
observer.observe(el, { childList: true, subtree: true });
|
|
checkFull(el, cb);
|
|
}
|
|
container.addEventListener("scroll", onScroll);
|
|
},
|
|
unmounted(el) {
|
|
const { container, onScroll } = el[SCOPE];
|
|
container == null ? void 0 : container.removeEventListener("scroll", onScroll);
|
|
destroyObserver(el);
|
|
}
|
|
};
|
|
|
|
exports.CHECK_INTERVAL = CHECK_INTERVAL;
|
|
exports.DEFAULT_DELAY = DEFAULT_DELAY;
|
|
exports.DEFAULT_DISTANCE = DEFAULT_DISTANCE;
|
|
exports.SCOPE = SCOPE;
|
|
exports["default"] = InfiniteScroll;
|
|
//# sourceMappingURL=index.js.map
|