useScrollTo.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
  3. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = useScrollTo;
  8. var _rcUtil = require("rc-util");
  9. var _raf = _interopRequireDefault(require("rc-util/lib/raf"));
  10. var _isVisible = _interopRequireDefault(require("rc-util/lib/Dom/isVisible"));
  11. var React = _interopRequireWildcard(require("react"));
  12. var SPEED_PTG = 1 / 3;
  13. function useScrollTo(ulRef, value) {
  14. // ========================= Scroll =========================
  15. var scrollingRef = React.useRef(false);
  16. var scrollRafRef = React.useRef(null);
  17. var scrollDistRef = React.useRef(null);
  18. var isScrolling = function isScrolling() {
  19. return scrollingRef.current;
  20. };
  21. var stopScroll = function stopScroll() {
  22. _raf.default.cancel(scrollRafRef.current);
  23. scrollingRef.current = false;
  24. };
  25. var scrollRafTimesRef = React.useRef();
  26. var startScroll = function startScroll() {
  27. var ul = ulRef.current;
  28. scrollDistRef.current = null;
  29. scrollRafTimesRef.current = 0;
  30. if (ul) {
  31. var targetLi = ul.querySelector("[data-value=\"".concat(value, "\"]"));
  32. var firstLi = ul.querySelector("li");
  33. var doScroll = function doScroll() {
  34. stopScroll();
  35. scrollingRef.current = true;
  36. scrollRafTimesRef.current += 1;
  37. var currentTop = ul.scrollTop;
  38. var firstLiTop = firstLi.offsetTop;
  39. var targetLiTop = targetLi.offsetTop;
  40. var targetTop = targetLiTop - firstLiTop;
  41. // Wait for element exist. 5 frames is enough
  42. if (targetLiTop === 0 && targetLi !== firstLi || !(0, _isVisible.default)(ul)) {
  43. if (scrollRafTimesRef.current <= 5) {
  44. scrollRafRef.current = (0, _raf.default)(doScroll);
  45. }
  46. return;
  47. }
  48. var nextTop = currentTop + (targetTop - currentTop) * SPEED_PTG;
  49. var dist = Math.abs(targetTop - nextTop);
  50. // Break if dist get larger, which means user is scrolling
  51. if (scrollDistRef.current !== null && scrollDistRef.current < dist) {
  52. stopScroll();
  53. return;
  54. }
  55. scrollDistRef.current = dist;
  56. // Stop when dist is less than 1
  57. if (dist <= 1) {
  58. ul.scrollTop = targetTop;
  59. stopScroll();
  60. return;
  61. }
  62. // IE not support `scrollTo`
  63. ul.scrollTop = nextTop;
  64. scrollRafRef.current = (0, _raf.default)(doScroll);
  65. };
  66. if (targetLi && firstLi) {
  67. doScroll();
  68. }
  69. }
  70. };
  71. // ======================== Trigger =========================
  72. var syncScroll = (0, _rcUtil.useEvent)(startScroll);
  73. return [syncScroll, stopScroll, isScrolling];
  74. }