UNPKG

5.07 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4Object.defineProperty(exports, "__esModule", {
5 value: true
6});
7exports["default"] = void 0;
8var _tslib = require("tslib");
9var _react = require("react");
10var _useEventListener = _interopRequireDefault(require("../useEventListener"));
11var _useLatest = _interopRequireDefault(require("../useLatest"));
12var _useMemoizedFn = _interopRequireDefault(require("../useMemoizedFn"));
13var _useSize = _interopRequireDefault(require("../useSize"));
14var _domTarget = require("../utils/domTarget");
15var _utils = require("../utils");
16var _useUpdateEffect = _interopRequireDefault(require("../useUpdateEffect"));
17var useVirtualList = function useVirtualList(list, options) {
18 var containerTarget = options.containerTarget,
19 wrapperTarget = options.wrapperTarget,
20 itemHeight = options.itemHeight,
21 _a = options.overscan,
22 overscan = _a === void 0 ? 5 : _a;
23 var itemHeightRef = (0, _useLatest["default"])(itemHeight);
24 var size = (0, _useSize["default"])(containerTarget);
25 var scrollTriggerByScrollToFunc = (0, _react.useRef)(false);
26 var _b = (0, _tslib.__read)((0, _react.useState)([]), 2),
27 targetList = _b[0],
28 setTargetList = _b[1];
29 var _c = (0, _tslib.__read)((0, _react.useState)({}), 2),
30 wrapperStyle = _c[0],
31 setWrapperStyle = _c[1];
32 var getVisibleCount = function getVisibleCount(containerHeight, fromIndex) {
33 if ((0, _utils.isNumber)(itemHeightRef.current)) {
34 return Math.ceil(containerHeight / itemHeightRef.current);
35 }
36 var sum = 0;
37 var endIndex = 0;
38 for (var i = fromIndex; i < list.length; i++) {
39 var height = itemHeightRef.current(i, list[i]);
40 sum += height;
41 endIndex = i;
42 if (sum >= containerHeight) {
43 break;
44 }
45 }
46 return endIndex - fromIndex;
47 };
48 var getOffset = function getOffset(scrollTop) {
49 if ((0, _utils.isNumber)(itemHeightRef.current)) {
50 return Math.floor(scrollTop / itemHeightRef.current) + 1;
51 }
52 var sum = 0;
53 var offset = 0;
54 for (var i = 0; i < list.length; i++) {
55 var height = itemHeightRef.current(i, list[i]);
56 sum += height;
57 if (sum >= scrollTop) {
58 offset = i;
59 break;
60 }
61 }
62 return offset + 1;
63 };
64 // 获取上部高度
65 var getDistanceTop = function getDistanceTop(index) {
66 if ((0, _utils.isNumber)(itemHeightRef.current)) {
67 var height_1 = index * itemHeightRef.current;
68 return height_1;
69 }
70 var height = list.slice(0, index).reduce(function (sum, _, i) {
71 return sum + itemHeightRef.current(i, list[i]);
72 }, 0);
73 return height;
74 };
75 var totalHeight = (0, _react.useMemo)(function () {
76 if ((0, _utils.isNumber)(itemHeightRef.current)) {
77 return list.length * itemHeightRef.current;
78 }
79 return list.reduce(function (sum, _, index) {
80 return sum + itemHeightRef.current(index, list[index]);
81 }, 0);
82 }, [list]);
83 var calculateRange = function calculateRange() {
84 var container = (0, _domTarget.getTargetElement)(containerTarget);
85 if (container) {
86 var scrollTop = container.scrollTop,
87 clientHeight = container.clientHeight;
88 var offset = getOffset(scrollTop);
89 var visibleCount = getVisibleCount(clientHeight, offset);
90 var start_1 = Math.max(0, offset - overscan);
91 var end = Math.min(list.length, offset + visibleCount + overscan);
92 var offsetTop = getDistanceTop(start_1);
93 setWrapperStyle({
94 height: totalHeight - offsetTop + 'px',
95 marginTop: offsetTop + 'px'
96 });
97 setTargetList(list.slice(start_1, end).map(function (ele, index) {
98 return {
99 data: ele,
100 index: index + start_1
101 };
102 }));
103 }
104 };
105 (0, _useUpdateEffect["default"])(function () {
106 var wrapper = (0, _domTarget.getTargetElement)(wrapperTarget);
107 if (wrapper) {
108 Object.keys(wrapperStyle).forEach(function (key) {
109 return wrapper.style[key] = wrapperStyle[key];
110 });
111 }
112 }, [wrapperStyle]);
113 (0, _react.useEffect)(function () {
114 if (!(size === null || size === void 0 ? void 0 : size.width) || !(size === null || size === void 0 ? void 0 : size.height)) {
115 return;
116 }
117 calculateRange();
118 }, [size === null || size === void 0 ? void 0 : size.width, size === null || size === void 0 ? void 0 : size.height, list]);
119 (0, _useEventListener["default"])('scroll', function (e) {
120 if (scrollTriggerByScrollToFunc.current) {
121 scrollTriggerByScrollToFunc.current = false;
122 return;
123 }
124 e.preventDefault();
125 calculateRange();
126 }, {
127 target: containerTarget
128 });
129 var scrollTo = function scrollTo(index) {
130 var container = (0, _domTarget.getTargetElement)(containerTarget);
131 if (container) {
132 scrollTriggerByScrollToFunc.current = true;
133 container.scrollTop = getDistanceTop(index);
134 calculateRange();
135 }
136 };
137 return [targetList, (0, _useMemoizedFn["default"])(scrollTo)];
138};
139var _default = useVirtualList;
140exports["default"] = _default;
\No newline at end of file