12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- import _typeof from "@babel/runtime/helpers/esm/typeof";
- import raf from '../../_util/raf';
- export default function useScrollTo(containerRef, mergedData, heights, props, getKey, collectHeight, syncScrollTop, triggerFlash) {
- var scroll;
- return function (arg) {
- // When not argument provided, we think dev may want to show the scrollbar
- if (arg === null || arg === undefined) {
- triggerFlash();
- return;
- }
- // Normal scroll logic
- raf.cancel(scroll);
- var data = mergedData.value;
- var itemHeight = props.itemHeight;
- if (typeof arg === 'number') {
- syncScrollTop(arg);
- } else if (arg && _typeof(arg) === 'object') {
- var index;
- var align = arg.align;
- if ('index' in arg) {
- index = arg.index;
- } else {
- index = data.findIndex(function (item) {
- return getKey(item) === arg.key;
- });
- }
- var _arg$offset = arg.offset,
- offset = _arg$offset === void 0 ? 0 : _arg$offset;
- // We will retry 3 times in case dynamic height shaking
- var syncScroll = function syncScroll(times, targetAlign) {
- if (times < 0 || !containerRef.value) return;
- var height = containerRef.value.clientHeight;
- var needCollectHeight = false;
- var newTargetAlign = targetAlign;
- // Go to next frame if height not exist
- if (height) {
- var mergedAlign = targetAlign || align;
- // Get top & bottom
- var stackTop = 0;
- var itemTop = 0;
- var itemBottom = 0;
- var maxLen = Math.min(data.length, index);
- for (var i = 0; i <= maxLen; i += 1) {
- var key = getKey(data[i]);
- itemTop = stackTop;
- var cacheHeight = heights.get(key);
- itemBottom = itemTop + (cacheHeight === undefined ? itemHeight : cacheHeight);
- stackTop = itemBottom;
- if (i === index && cacheHeight === undefined) {
- needCollectHeight = true;
- }
- }
- var scrollTop = containerRef.value.scrollTop;
- // Scroll to
- var targetTop = null;
- switch (mergedAlign) {
- case 'top':
- targetTop = itemTop - offset;
- break;
- case 'bottom':
- targetTop = itemBottom - height + offset;
- break;
- default:
- {
- var scrollBottom = scrollTop + height;
- if (itemTop < scrollTop) {
- newTargetAlign = 'top';
- } else if (itemBottom > scrollBottom) {
- newTargetAlign = 'bottom';
- }
- }
- }
- if (targetTop !== null && targetTop !== scrollTop) {
- syncScrollTop(targetTop);
- }
- }
- // We will retry since element may not sync height as it described
- scroll = raf(function () {
- if (needCollectHeight) {
- collectHeight();
- }
- syncScroll(times - 1, newTargetAlign);
- }, 2);
- };
- syncScroll(5);
- }
- };
- }
|