useScrollTo.js 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = useScrollTo;
  7. var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
  8. var _raf = _interopRequireDefault(require("../../_util/raf"));
  9. function useScrollTo(containerRef, mergedData, heights, props, getKey, collectHeight, syncScrollTop, triggerFlash) {
  10. var scroll;
  11. return function (arg) {
  12. // When not argument provided, we think dev may want to show the scrollbar
  13. if (arg === null || arg === undefined) {
  14. triggerFlash();
  15. return;
  16. }
  17. // Normal scroll logic
  18. _raf.default.cancel(scroll);
  19. var data = mergedData.value;
  20. var itemHeight = props.itemHeight;
  21. if (typeof arg === 'number') {
  22. syncScrollTop(arg);
  23. } else if (arg && (0, _typeof2.default)(arg) === 'object') {
  24. var index;
  25. var align = arg.align;
  26. if ('index' in arg) {
  27. index = arg.index;
  28. } else {
  29. index = data.findIndex(function (item) {
  30. return getKey(item) === arg.key;
  31. });
  32. }
  33. var _arg$offset = arg.offset,
  34. offset = _arg$offset === void 0 ? 0 : _arg$offset;
  35. // We will retry 3 times in case dynamic height shaking
  36. var syncScroll = function syncScroll(times, targetAlign) {
  37. if (times < 0 || !containerRef.value) return;
  38. var height = containerRef.value.clientHeight;
  39. var needCollectHeight = false;
  40. var newTargetAlign = targetAlign;
  41. // Go to next frame if height not exist
  42. if (height) {
  43. var mergedAlign = targetAlign || align;
  44. // Get top & bottom
  45. var stackTop = 0;
  46. var itemTop = 0;
  47. var itemBottom = 0;
  48. var maxLen = Math.min(data.length, index);
  49. for (var i = 0; i <= maxLen; i += 1) {
  50. var key = getKey(data[i]);
  51. itemTop = stackTop;
  52. var cacheHeight = heights.get(key);
  53. itemBottom = itemTop + (cacheHeight === undefined ? itemHeight : cacheHeight);
  54. stackTop = itemBottom;
  55. if (i === index && cacheHeight === undefined) {
  56. needCollectHeight = true;
  57. }
  58. }
  59. var scrollTop = containerRef.value.scrollTop;
  60. // Scroll to
  61. var targetTop = null;
  62. switch (mergedAlign) {
  63. case 'top':
  64. targetTop = itemTop - offset;
  65. break;
  66. case 'bottom':
  67. targetTop = itemBottom - height + offset;
  68. break;
  69. default:
  70. {
  71. var scrollBottom = scrollTop + height;
  72. if (itemTop < scrollTop) {
  73. newTargetAlign = 'top';
  74. } else if (itemBottom > scrollBottom) {
  75. newTargetAlign = 'bottom';
  76. }
  77. }
  78. }
  79. if (targetTop !== null && targetTop !== scrollTop) {
  80. syncScrollTop(targetTop);
  81. }
  82. }
  83. // We will retry since element may not sync height as it described
  84. scroll = (0, _raf.default)(function () {
  85. if (needCollectHeight) {
  86. collectHeight();
  87. }
  88. syncScroll(times - 1, newTargetAlign);
  89. });
  90. };
  91. syncScroll(5);
  92. }
  93. };
  94. }