UNPKG

ten-design-vue

Version:

ten-vue

244 lines (199 loc) 7.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _debounce = _interopRequireDefault(require("lodash/debounce")); var _helper = require("../scripts/utils/helper"); var _domHelper = _interopRequireDefault(require("../scripts/utils/dom-helper")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } var getStyleComputedProperty = function getStyleComputedProperty(element, property) { if (element === window) { element = document.documentElement; } if (element.nodeType !== 1) { return []; } // NOTE: 1 DOM access here var css = window.getComputedStyle(element, null); return property ? css[property] : css; }; var entries = function entries(obj) { return Object.keys(obj || {}).map(function (key) { return [key, obj[key]]; }); }; var getPositionSize = function getPositionSize(el, prop) { return el === window || el === document ? document.documentElement[prop] : el[prop]; }; var getOffsetHeight = function getOffsetHeight(el) { return getPositionSize(el, 'offsetHeight'); }; var getClientHeight = function getClientHeight(el) { return getPositionSize(el, 'clientHeight'); }; var scope = 'TenInfiniteScroll'; var attributes = { /** * 节流时延,单位为ms */ delay: { type: Number, default: 200 }, /** * 触发加载的距离阈值,单位为px */ distance: { type: Number, default: 0 }, /** * 是否禁用 */ disabled: { type: Boolean, default: false }, /** * 是否立即执行加载方法,以防初始状态下内容无法撑满容器。 */ immediate: { type: Boolean, default: true } }; var getScrollOptions = function getScrollOptions(el, vm) { if (!(0, _helper.isHtmlElement)(el)) return {}; return entries(attributes).reduce(function (map, _ref) { var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], option = _ref2[1]; var type = option.type, defaultValue = option.default; var value = el.getAttribute("infinite-scroll-".concat(key)); value = (0, _helper.isUndefined)(vm[value]) ? value : vm[value]; switch (type) { case Number: value = Number(value); value = Number.isNaN(value) ? defaultValue : value; break; case Boolean: // eslint-disable-next-line value = (0, _helper.isDefined)(value) ? value === 'false' ? false : Boolean(value) : defaultValue; break; default: value = type(value); } map[key] = value; return map; }, {}); }; var getElementTop = function getElementTop(el) { return el.getBoundingClientRect().top; }; var handleScroll = function handleScroll(cb) { var _this$scope = this[scope], el = _this$scope.el, vm = _this$scope.vm, container = _this$scope.container, observer = _this$scope.observer; var _getScrollOptions = getScrollOptions(el, vm), distance = _getScrollOptions.distance, disabled = _getScrollOptions.disabled; if (disabled) return; var containerInfo = container.getBoundingClientRect(); if (!containerInfo.width && !containerInfo.height) return; var shouldTrigger = false; if (container === el) { // be aware of difference between clientHeight & offsetHeight & window.getComputedStyle().height var scrollBottom = container.scrollTop + getClientHeight(container); shouldTrigger = container.scrollHeight - scrollBottom <= distance; } else { var heightBelowTop = getOffsetHeight(el) + getElementTop(el) - getElementTop(container); var offsetHeight = getOffsetHeight(container); var borderBottom = Number.parseFloat(getStyleComputedProperty(container, 'borderBottomWidth')); shouldTrigger = heightBelowTop - offsetHeight + borderBottom <= distance; } if (shouldTrigger && (0, _helper.isFunction)(cb)) { cb.call(vm); } else if (observer) { observer.disconnect(); this[scope].observer = null; } }; var _default = { name: 'infinite-scroll', // 此处的 props 仅用于生成文档,需要跟 attributes 属性同步更新 props: { /** * 节流时延,单位为ms */ delay: { type: Number, default: 200 }, /** * 触发加载的距离阈值,单位为px */ distance: { type: Number, default: 0 }, /** * 是否禁用 */ disabled: { type: Boolean, default: false }, /** * 是否立即执行加载方法,以防初始状态下内容无法撑满容器。 */ immediate: { type: Boolean, default: true } }, inserted: function inserted(el, binding, vnode) { var cb = binding.value; var vm = vnode.context; // only include vertical scroll var container = _domHelper.default.getScrollContainer(el, true); var _getScrollOptions2 = getScrollOptions(el, vm), delay = _getScrollOptions2.delay, immediate = _getScrollOptions2.immediate; var onScroll = (0, _debounce.default)(handleScroll.bind(el, cb), delay); el[scope] = { el: el, vm: vm, container: container, onScroll: onScroll }; if (container) { container.addEventListener('scroll', onScroll); if (immediate) { el[scope].observer = new MutationObserver(onScroll); var observer = el[scope].observer; observer.observe(container, { childList: true, subtree: true }); onScroll(); } } }, unbind: function unbind(el) { var _el$scope = el[scope], container = _el$scope.container, onScroll = _el$scope.onScroll; if (container) { container.removeEventListener('scroll', onScroll); } } }; exports.default = _default;