196 lines
4.5 KiB
JavaScript
196 lines
4.5 KiB
JavaScript
"use strict";
|
|
|
|
var __read = this && this.__read || function (o, n) {
|
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
if (!m) return o;
|
|
var i = m.call(o),
|
|
r,
|
|
ar = [],
|
|
e;
|
|
|
|
try {
|
|
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) {
|
|
ar.push(r.value);
|
|
}
|
|
} catch (error) {
|
|
e = {
|
|
error: error
|
|
};
|
|
} finally {
|
|
try {
|
|
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
} finally {
|
|
if (e) throw e.error;
|
|
}
|
|
}
|
|
|
|
return ar;
|
|
};
|
|
|
|
var __importDefault = this && this.__importDefault || function (mod) {
|
|
return mod && mod.__esModule ? mod : {
|
|
"default": mod
|
|
};
|
|
};
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var react_1 = require("react");
|
|
|
|
var useSize_1 = __importDefault(require("../useSize"));
|
|
|
|
exports["default"] = function (list, options) {
|
|
var containerRef = react_1.useRef();
|
|
var size = useSize_1["default"](containerRef); // 暂时禁止 cache
|
|
// const distanceCache = useRef<{ [key: number]: number }>({});
|
|
|
|
var _a = __read(react_1.useState({
|
|
start: 0,
|
|
end: 10
|
|
}), 2),
|
|
state = _a[0],
|
|
setState = _a[1];
|
|
|
|
var itemHeight = options.itemHeight,
|
|
_b = options.overscan,
|
|
overscan = _b === void 0 ? 5 : _b;
|
|
|
|
if (!itemHeight) {
|
|
console.warn('please enter a valid itemHeight');
|
|
}
|
|
|
|
var getViewCapacity = function getViewCapacity(containerHeight) {
|
|
if (typeof itemHeight === 'number') {
|
|
return Math.ceil(containerHeight / itemHeight);
|
|
}
|
|
|
|
var _a = state.start,
|
|
start = _a === void 0 ? 0 : _a;
|
|
var sum = 0;
|
|
var capacity = 0;
|
|
|
|
for (var i = start; i < list.length; i++) {
|
|
var height = itemHeight(i, list[i]);
|
|
sum += height;
|
|
|
|
if (sum >= containerHeight) {
|
|
capacity = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return capacity - start;
|
|
};
|
|
|
|
var getOffset = function getOffset(scrollTop) {
|
|
if (typeof itemHeight === 'number') {
|
|
return Math.floor(scrollTop / itemHeight) + 1;
|
|
}
|
|
|
|
var sum = 0;
|
|
var offset = 0;
|
|
|
|
for (var i = 0; i < list.length; i++) {
|
|
var height = itemHeight(i, list[i]);
|
|
sum += height;
|
|
|
|
if (sum >= scrollTop) {
|
|
offset = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return offset + 1;
|
|
};
|
|
|
|
var calculateRange = function calculateRange() {
|
|
var element = containerRef.current;
|
|
|
|
if (element) {
|
|
var offset = getOffset(element.scrollTop);
|
|
var viewCapacity = getViewCapacity(element.clientHeight);
|
|
var from = offset - overscan;
|
|
var to = offset + viewCapacity + overscan;
|
|
setState({
|
|
start: from < 0 ? 0 : from,
|
|
end: to > list.length ? list.length : to
|
|
});
|
|
}
|
|
};
|
|
|
|
react_1.useEffect(function () {
|
|
calculateRange();
|
|
}, [size.width, size.height, list.length]);
|
|
var totalHeight = react_1.useMemo(function () {
|
|
if (typeof itemHeight === 'number') {
|
|
return list.length * itemHeight;
|
|
}
|
|
|
|
return list.reduce(function (sum, _, index) {
|
|
return sum + itemHeight(index, list[index]);
|
|
}, 0);
|
|
}, [list.length]);
|
|
|
|
var getDistanceTop = function getDistanceTop(index) {
|
|
// 如果有缓存,优先返回缓存值
|
|
// if (enableCache && distanceCache.current[index]) {
|
|
// return distanceCache.current[index];
|
|
// }
|
|
if (typeof itemHeight === 'number') {
|
|
var height_1 = index * itemHeight; // if (enableCache) {
|
|
// distanceCache.current[index] = height;
|
|
// }
|
|
|
|
return height_1;
|
|
}
|
|
|
|
var height = list.slice(0, index).reduce(function (sum, _, i) {
|
|
return sum + itemHeight(i, list[i]);
|
|
}, 0); // if (enableCache) {
|
|
// distanceCache.current[index] = height;
|
|
// }
|
|
|
|
return height;
|
|
};
|
|
|
|
var scrollTo = function scrollTo(index) {
|
|
if (containerRef.current) {
|
|
containerRef.current.scrollTop = getDistanceTop(index);
|
|
calculateRange();
|
|
}
|
|
};
|
|
|
|
var offsetTop = react_1.useMemo(function () {
|
|
return getDistanceTop(state.start);
|
|
}, [state.start]);
|
|
return {
|
|
list: list.slice(state.start, state.end).map(function (ele, index) {
|
|
return {
|
|
data: ele,
|
|
index: index + state.start
|
|
};
|
|
}),
|
|
scrollTo: scrollTo,
|
|
containerProps: {
|
|
ref: function ref(ele) {
|
|
containerRef.current = ele;
|
|
},
|
|
onScroll: function onScroll(e) {
|
|
e.preventDefault();
|
|
calculateRange();
|
|
},
|
|
style: {
|
|
overflowY: 'auto'
|
|
}
|
|
},
|
|
wrapperProps: {
|
|
style: {
|
|
width: '100%',
|
|
height: totalHeight - offsetTop,
|
|
marginTop: offsetTop
|
|
}
|
|
}
|
|
};
|
|
}; |