ten-design-vue
Version:
ten-vue
244 lines (199 loc) • 7.37 kB
JavaScript
;
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;