React——封装滑动到底部加载
代码】React——封装滑动到底部加载。
·
1. 方案一:新建scroll.tsx组件(通过监听滚动事件)
import React from "react";
namespace ScrollSpace {
export type Props = {
children?: React.ReactNode
height?: string //高度
load?: (data?: Event) => void //执行函数
interval?: number //离底部的间隔内加载执行,默认20
delay?: number //延迟时间,默认1000毫秒
}
export type Event = React.UIEvent<HTMLDivElement, UIEvent>
}
/* 滑动加载组件 */
export const Scroll: React.FC<ScrollSpace.Props> = (props) => {
props = Object.assign({ interval: 20, load: () => { } }, props)
return <div style={{ height: props.height, overflow: "auto" }} onScroll={debounce<ScrollSpace.Event>((data) => {
let divEl = data.target as HTMLDivElement
if (divEl.scrollTop + divEl.clientHeight + props.interval! > divEl.scrollHeight) {
props.load!(data)
}
}, props.delay)}>
{props.children}
</div>
}
/* 防抖默认1秒 */
function debounce<T>(fn: (data: T) => void, delay: number = 1000) {
let timeout: NodeJS.Timeout | null = null;
return function (data: T) {
if (timeout !== null) clearTimeout(timeout);
timeout = setTimeout(fn.bind({}, data), delay);
}
}
组件属性 | 类型 | 备注 |
---|---|---|
children | React.ReactNode | 插槽 |
height | string | 高度 |
load | Function(Event) | 滑动到底部执行的函数 |
interval | number | 距离底部的间隔,默认20 |
delay | number | 函数执行的延迟时间,默认1000毫秒 |
1.2. 使用
import { Scroll } from "../Scroll/index"
function Index() {
const [list,setList] = useState<React.ReactNode[]>([])
/* 生成数据 */
useEffect(()=>{
setList(
new Array(100).fill(null).map((_item, index) => {
return <Col span={24} key={index}>【】【】【】【】【】】【】</Col>
})
)
},[])
return <Scroll height="100%" interval={500} load={(data) => {
console.log("到底部了")
}}>
<Row>
{list}
</Row>
</Scroll>
}
2. 方案二:新建scroll.tsx组件(通过观察者实现)
import React, { useEffect, useRef } from "react";
namespace ScrollSpace {
export type Props = {
children?: React.ReactNode
height?: string //高度,默认100%
load?: (data?: IntersectionObserverEntry) => void //执行函数
isFirstLoad?: boolean //首次进入是否执行,默认true
}
}
/* 滑动加载组件 */
export const Scroll: React.FC<ScrollSpace.Props> = (props) => {
const loadingRef = useRef<HTMLSpanElement>(null)
props = Object.assign({ load: () => { }, height: "100%", isFirstLoad: true }, props)
useEffect(() => {
let isFirst = props.isFirstLoad
let ob = new IntersectionObserver(([entries]:IntersectionObserverEntry[]) => {
if (entries.isIntersecting && isFirst) {
props.load!(entries)
}
isFirst = true
}, { threshold: 1 })
ob.observe(loadingRef.current as HTMLSpanElement)
}, [])
return <div style={{ height: props.height, overflow: "auto" }}>
{props.children}
<span ref={loadingRef}>loading...</span>
</div>
}
组件属性 | 类型 | 备注 |
---|---|---|
children | React.ReactNode | 插槽 |
height | string | 高度 |
load | Function(Event) | 滑动到底部执行的函数 |
isFirstLoad | boolean | 首次进入是否执行,默认true |
使用方法与方案一一样
更多推荐
所有评论(0)