123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- import { useEvent } from 'rc-util';
- import raf from "rc-util/es/raf";
- import isVisible from "rc-util/es/Dom/isVisible";
- import * as React from 'react';
- var SPEED_PTG = 1 / 3;
- export default function useScrollTo(ulRef, value) {
- // ========================= Scroll =========================
- var scrollingRef = React.useRef(false);
- var scrollRafRef = React.useRef(null);
- var scrollDistRef = React.useRef(null);
- var isScrolling = function isScrolling() {
- return scrollingRef.current;
- };
- var stopScroll = function stopScroll() {
- raf.cancel(scrollRafRef.current);
- scrollingRef.current = false;
- };
- var scrollRafTimesRef = React.useRef();
- var startScroll = function startScroll() {
- var ul = ulRef.current;
- scrollDistRef.current = null;
- scrollRafTimesRef.current = 0;
- if (ul) {
- var targetLi = ul.querySelector("[data-value=\"".concat(value, "\"]"));
- var firstLi = ul.querySelector("li");
- var doScroll = function doScroll() {
- stopScroll();
- scrollingRef.current = true;
- scrollRafTimesRef.current += 1;
- var currentTop = ul.scrollTop;
- var firstLiTop = firstLi.offsetTop;
- var targetLiTop = targetLi.offsetTop;
- var targetTop = targetLiTop - firstLiTop;
- // Wait for element exist. 5 frames is enough
- if (targetLiTop === 0 && targetLi !== firstLi || !isVisible(ul)) {
- if (scrollRafTimesRef.current <= 5) {
- scrollRafRef.current = raf(doScroll);
- }
- return;
- }
- var nextTop = currentTop + (targetTop - currentTop) * SPEED_PTG;
- var dist = Math.abs(targetTop - nextTop);
- // Break if dist get larger, which means user is scrolling
- if (scrollDistRef.current !== null && scrollDistRef.current < dist) {
- stopScroll();
- return;
- }
- scrollDistRef.current = dist;
- // Stop when dist is less than 1
- if (dist <= 1) {
- ul.scrollTop = targetTop;
- stopScroll();
- return;
- }
- // IE not support `scrollTo`
- ul.scrollTop = nextTop;
- scrollRafRef.current = raf(doScroll);
- };
- if (targetLi && firstLi) {
- doScroll();
- }
- }
- };
- // ======================== Trigger =========================
- var syncScroll = useEvent(startScroll);
- return [syncScroll, stopScroll, isScrolling];
- }
|