Skip to content

Commit

Permalink
refactor: sticky (#2468)
Browse files Browse the repository at this point in the history
  • Loading branch information
oasis-cloud authored Jul 23, 2024
1 parent 6f422ed commit bac23e4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 76 deletions.
75 changes: 37 additions & 38 deletions src/packages/sticky/sticky.taro.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import React, {
FunctionComponent,
useRef,
useState,
useMemo,
CSSProperties,
FunctionComponent,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react'
import classNames from 'classnames'
import {
getEnv,
getSystemInfoSync,
PageScrollObject,
usePageScroll,
getSystemInfoSync,
getEnv,
} from '@tarojs/taro'
import { BasicComponent, ComponentDefaults } from '@/utils/typings'
import useWatch from '@/utils/use-watch'
Expand Down Expand Up @@ -72,12 +72,10 @@ export const Sticky: FunctionComponent<Partial<StickyProps>> = (props) => {
width: '',
}
}
const style: CSSProperties = {}
if (rootRect.height) {
style.height = rootRect.height
}
if (rootRect.width) {
style.width = rootRect.width

const style: CSSProperties = {
height: rootRect.height ?? '',
width: rootRect.width ?? '',
}
return style
}, [fixed, rootRect.height, rootRect.width])
Expand All @@ -87,46 +85,47 @@ export const Sticky: FunctionComponent<Partial<StickyProps>> = (props) => {
return {
height: '',
width: '',
[position as string]: '',
[position]: '',
}
}
const style: CSSProperties = {}
if (rootRect.height) style.height = rootRect.height
if (rootRect.width) style.width = rootRect.width
style.transform = `translate3d(0, ${transform}px, 0)`
style[position] = threshold
style.zIndex = zIndex
const style: CSSProperties = {
height: rootRect.height ?? '',
width: rootRect.width ?? '',
transform: `translate3d(0, ${transform}px, 0)`,
[position]: threshold,
zIndex,
}
return style
}, [fixed, rootRect.height, rootRect.width, transform, position])

const handleScroll: any = async (scrollTop: number) => {
const curRootRect = await getRectByTaro(rootRef.current)
const stickyRect = await getRectByTaro(stickyRef.current)
if (curRootRect && stickyRect) {
setRootRect(curRootRect)
if (position === 'top') {
if (container) {
const containerRect = await getRectByTaro(container.current)
const difference =
containerRect.bottom - threshold - curRootRect.height
const curTransform = difference < 0 ? difference : 0
setTransform(curTransform)
const curFixed =
threshold > curRootRect.top && containerRect.bottom > 0
setFixed(curFixed)
} else {
setFixed(threshold > curRootRect.top)
}
if (!curRootRect || !stickyRect) {
console.warn('getRectByTaro获取失败', { stickyRect, curRootRect })
return
}

setRootRect(curRootRect)

if (position === 'top') {
if (container) {
const containerRect = await getRectByTaro(container.current)
const difference = containerRect.bottom - threshold - curRootRect.height
const curTransform = difference < 0 ? difference : 0
setTransform(curTransform)
const curFixed = threshold > curRootRect.top && containerRect.bottom > 0
setFixed(curFixed)
} else {
const windowHeight = getSystemInfoSync().windowHeight
setFixed(windowHeight - threshold < curRootRect.bottom)
setFixed(threshold > curRootRect.top)
}
} else {
console.warn('getRectByTaro获取失败', { stickyRect, curRootRect })
const windowHeight = getSystemInfoSync().windowHeight
setFixed(windowHeight - threshold < curRootRect.bottom)
}
}
const getElement = useCallback(() => {
return getScrollParent(rootRef.current as HTMLElement)
return getScrollParent(rootRef.current)
}, [])

useEffect(() => {
Expand Down
67 changes: 30 additions & 37 deletions src/packages/sticky/sticky.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, {
CSSProperties,
FunctionComponent,
useEffect,
useCallback,
useEffect,
useRef,
useState,
CSSProperties,
} from 'react'
import classNames from 'classnames'
import { getScrollParent } from '@/utils/get-scroll-parent'
Expand Down Expand Up @@ -58,14 +58,15 @@ export const Sticky: FunctionComponent<Partial<StickyProps>> = (props) => {

useEffect(() => {
if (position === 'top') return
const containerEle = container?.current as HTMLElement
const containerEle = container && container.current
const rootEle = rootRef.current
const stickyEle = stickyRef.current

if (!rootRef.current && !containerEle) return
const rootRect = getRect(rootRef.current as Element)
if (!rootEle && !containerEle) return
const rootRect = getRect(rootEle)

Check failure on line 66 in src/packages/sticky/sticky.tsx

View workflow job for this annotation

GitHub Actions / build

Argument of type 'HTMLDivElement | null' is not assignable to parameter of type 'Element | Window | undefined'.
const containerRect = getRect(containerEle)

Check failure on line 67 in src/packages/sticky/sticky.tsx

View workflow job for this annotation

GitHub Actions / build

Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | Window | undefined'.
const clientHeight = document.documentElement.clientHeight
const stCurrent = stickyRef.current as Element
const stickyRect = getRect(stCurrent)
const stickyRect = getRect(stickyEle)

Check failure on line 69 in src/packages/sticky/sticky.tsx

View workflow job for this annotation

GitHub Actions / build

Argument of type 'HTMLDivElement | null' is not assignable to parameter of type 'Element | Window | undefined'.
let fixed = clientHeight - threshold < rootRect.bottom
if (containerEle) {
fixed =
Expand All @@ -82,21 +83,19 @@ export const Sticky: FunctionComponent<Partial<StickyProps>> = (props) => {
setIsFixed(fixed)
}, [position, container, threshold])
const handleScroll = useCallback(() => {
const containerEle = container?.current as HTMLElement
const containerEle = container && container.current
const rootEle = rootRef.current
const stickyEle = stickyRef.current
if (!rootEle && !containerEle) return

if (!rootRef.current && !containerEle) return

const rootRect = getRect(rootRef.current as Element)
const stCurrent = stickyRef.current as Element
const stickyRect = getRect(stCurrent)
const rootRect = getRect(rootEle)

Check failure on line 91 in src/packages/sticky/sticky.tsx

View workflow job for this annotation

GitHub Actions / build

Argument of type 'HTMLDivElement | null' is not assignable to parameter of type 'Element | Window | undefined'.
const stickyRect = getRect(stickyEle)

Check failure on line 92 in src/packages/sticky/sticky.tsx

View workflow job for this annotation

GitHub Actions / build

Argument of type 'HTMLDivElement | null' is not assignable to parameter of type 'Element | Window | undefined'.
const containerRect = getRect(containerEle)

Check failure on line 93 in src/packages/sticky/sticky.tsx

View workflow job for this annotation

GitHub Actions / build

Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | Window | undefined'.
if (rootRect.height) {
setRootStyle((prev) => {
return {
...prev,
height: rootRect.height,
}
})
setRootStyle((prev) => ({
...prev,
height: rootRect.height,
}))
}

const getFixed = () => {
Expand All @@ -119,22 +118,16 @@ export const Sticky: FunctionComponent<Partial<StickyProps>> = (props) => {
}

const getTransform = (): CSSProperties => {
if (position === 'top') {
if (containerEle) {
const diff = containerRect.bottom - threshold - stickyRect.height
const transform = diff < 0 ? diff : 0
return { transform: `translate3d(0, ${transform}px, 0)` }
}
return {}
if (position === 'top' && containerEle) {
const diff = containerRect.bottom - threshold - stickyRect.height
const transform = diff < 0 ? diff : 0
return { transform: `translate3d(0, ${transform}px, 0)` }
}
if (position === 'bottom') {
if (containerEle) {
const clientHeight = document.documentElement.clientHeight
const diff = containerRect.bottom - (clientHeight - threshold)
const transform = diff < 0 ? diff : 0
return { transform: `translate3d(0, ${transform}px, 0)` }
}
return {}
if (position === 'bottom' && containerEle) {
const clientHeight = document.documentElement.clientHeight
const diff = containerRect.bottom - (clientHeight - threshold)
const transform = diff < 0 ? diff : 0
return { transform: `translate3d(0, ${transform}px, 0)` }
}
return {}
}
Expand All @@ -153,10 +146,10 @@ export const Sticky: FunctionComponent<Partial<StickyProps>> = (props) => {
onChange && onChange(isFixed)
})
useEffect(() => {
const el = getElement() as HTMLElement | Window
el.addEventListener('scroll', handleScroll, false)
const el = getElement()
el?.addEventListener('scroll', handleScroll, false)
return () => {
el.removeEventListener('scroll', handleScroll)
el?.removeEventListener('scroll', handleScroll)
}
}, [getElement, handleScroll])

Expand Down
2 changes: 1 addition & 1 deletion src/utils/get-scroll-parent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function isElement(node: Element) {
}

export function getScrollParent(
el: Element,
el: Element | null | undefined,
root: ScrollElement | null | undefined = defaultRoot
): Window | Element | null | undefined {
let node = el
Expand Down

0 comments on commit bac23e4

Please sign in to comment.