Skip to content

Commit

Permalink
fix: useLockScroll whether the element scroll is in the end #6253 (#6254
Browse files Browse the repository at this point in the history
)

* fix: useLockScroll whether the element scroll is in the end #6253

* test: useLockScroll test case #6253

* fix: useLockScroll whether the element scroll is in the end #6253

* test: useLockScroll whether the element scroll is in the end #6253

* test: useLockScroll with strict params #6253

* test: useLockScroll with strict params #6253

* fix: del px and remove {} #6253
  • Loading branch information
19Qingfeng authored Aug 10, 2023
1 parent a76c9b0 commit 46ffd90
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 3 deletions.
154 changes: 152 additions & 2 deletions src/utils/tests/use-lock-scroll.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,48 @@
import React, { useRef, createRef } from 'react'
import { render, fireEvent, screen, createEvent } from 'testing'
import React, { useRef } from 'react'
import { render, fireEvent, createEvent, screen } from 'testing'
import { useLockScroll } from '../use-lock-scroll'

describe('useLockScroll', () => {
let TestComponent: React.FC<{
scrollParams: boolean | 'strict'
handleTouch?: () => void
}>

beforeEach(() => {
TestComponent = (props: {
scrollParams: boolean | 'strict'
handleTouch?: () => void
}) => {
const divRef = useRef<HTMLDivElement>(null)

useLockScroll(divRef, props.scrollParams)

return (
<div
ref={divRef}
data-testid='lock'
style={{
height: 200,
overflow: 'scroll',
cursor: 'grab',
touchAction: 'none',
}}
onTouchMove={() => props.handleTouch && props.handleTouch()}
>
{new Array(10).fill({}).map((_, i) => (
<h1 key={i} style={{ height: 25 }}>
Test component {i}
</h1>
))}
</div>
)
}
})

afterEach(() => {
TestComponent = null as any
})

test('use preventDefault when event listener is treated as as passive', () => {
const handleTouch = jest.fn()
const TestComponent = () => {
Expand Down Expand Up @@ -32,4 +72,114 @@ describe('useLockScroll', () => {

expect(fn).toBeCalled()
})

test('Scroll To Bottom', async () => {
const { getByTestId } = render(<TestComponent scrollParams={true} />)

const testEl = getByTestId('lock')

jest.spyOn(testEl, 'scrollHeight', 'get').mockImplementation(() => 200)

const scrollTop = jest.spyOn(testEl, 'scrollTop', 'get')
scrollTop.mockImplementationOnce(() => 150)

jest.spyOn(testEl, 'getBoundingClientRect').mockImplementation(() => ({
height: 20,
top: 0,
left: 0,
x: 0,
y: 0,
bottom: 0,
right: 0,
width: 0,
toJSON: () => {},
}))

fireEvent.touchStart(testEl, {
touches: [{ clientX: 0, clientY: 100 }],
})

const triggerTruthy = fireEvent.touchMove(testEl, {
touches: [{ clientX: 0, clientY: 20 }],
})
// 滚动事件正常触发
expect(triggerTruthy).toBeTruthy()

// 滚动高度到 180
scrollTop.mockImplementationOnce(() => 180)

const triggerFalsy = fireEvent.touchMove(testEl, {
touches: [{ clientX: 0, clientY: 10 }],
})

// 滚动事件被取消
expect(triggerFalsy).toBeFalsy()
})

test('Scroll To Top', async () => {
const { getByTestId } = render(<TestComponent scrollParams={true} />)

const testEl = getByTestId('lock')

jest.spyOn(testEl, 'scrollHeight', 'get').mockImplementation(() => 200)

const scrollTop = jest.spyOn(testEl, 'scrollTop', 'get')
scrollTop.mockImplementationOnce(() => 150)

jest.spyOn(testEl, 'getBoundingClientRect').mockImplementation(() => ({
height: 20,
top: 0,
left: 0,
x: 0,
y: 0,
bottom: 0,
right: 0,
width: 0,
toJSON: () => {},
}))

fireEvent.touchStart(testEl, {
touches: [{ clientX: 0, clientY: 100 }],
})

const triggerTruthy = fireEvent.touchMove(testEl, {
touches: [{ clientX: 0, clientY: 120 }],
})
// 滚动事件正常触发
expect(triggerTruthy).toBeTruthy()

// 滚动高度到顶部
scrollTop.mockImplementationOnce(() => 0)

const triggerFalsy = fireEvent.touchMove(testEl, {
touches: [{ clientX: 0, clientY: 200 }],
})

// 滚动事件被取消
expect(triggerFalsy).toBeFalsy()
})

test('Scroll With Strict Params', async () => {
const { getByTestId } = render(<TestComponent scrollParams='strict' />)

const testEl = getByTestId('lock')

jest
.spyOn(document.body, 'clientHeight', 'get')
.mockImplementation(() => 20)
jest
.spyOn(document.body, 'scrollHeight', 'get')
.mockImplementation(() => 30)

fireEvent.touchStart(testEl, {
touches: [{ clientX: 0, clientY: 100 }],
})

const cancelTrigger = fireEvent.touchMove(testEl, {
touches: [{ clientX: 0, clientY: 200 }],
})

// 事件被取消
expect(cancelTrigger).toBeFalsy()
})
})
3 changes: 2 additions & 1 deletion src/utils/use-lock-scroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ export function useLockScroll(
}

const { scrollHeight, offsetHeight, scrollTop } = el
const { height } = el.getBoundingClientRect()
let status = '11'

if (scrollTop === 0) {
status = offsetHeight >= scrollHeight ? '00' : '01'
} else if (scrollTop + offsetHeight >= scrollHeight) {
} else if (scrollHeight <= Math.round(height + scrollTop)) {
status = '10'
}

Expand Down

0 comments on commit 46ffd90

Please sign in to comment.