wwf
2025-05-20 938c3e5a587ce950a94964ea509b9e7f8834dfae
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import React from 'react'
import { useThrottleFn } from 'ahooks'
 
export enum ScrollPosition {
  belowTheWrap = 'belowTheWrap',
  showing = 'showing',
  aboveTheWrap = 'aboveTheWrap',
}
 
type Params = {
  wrapElemRef: React.RefObject<HTMLElement>
  nextToStickyELemRef: React.RefObject<HTMLElement>
}
const useStickyScroll = ({
  wrapElemRef,
  nextToStickyELemRef,
}: Params) => {
  const [scrollPosition, setScrollPosition] = React.useState<ScrollPosition>(ScrollPosition.belowTheWrap)
  const { run: handleScroll } = useThrottleFn(() => {
    const wrapDom = wrapElemRef.current
    const stickyDOM = nextToStickyELemRef.current
    if (!wrapDom || !stickyDOM)
      return
    const { height: wrapHeight, top: wrapTop } = wrapDom.getBoundingClientRect()
    const { top: nextToStickyTop } = stickyDOM.getBoundingClientRect()
    let scrollPositionNew = ScrollPosition.belowTheWrap
 
    if (nextToStickyTop - wrapTop >= wrapHeight)
      scrollPositionNew = ScrollPosition.belowTheWrap
    else if (nextToStickyTop <= wrapTop)
      scrollPositionNew = ScrollPosition.aboveTheWrap
    else
      scrollPositionNew = ScrollPosition.showing
 
    if (scrollPosition !== scrollPositionNew)
      setScrollPosition(scrollPositionNew)
  }, { wait: 100 })
 
  return {
    handleScroll,
    scrollPosition,
  }
}
 
export default useStickyScroll