useBigScreenScroll
原理
每隔2s,列表向上移动(利用css3 transition)一个item的高度,动画完毕后,将第一个item的数据,移到列表的最后面。
使用
import useBigScreenScroll from './useBigScreenScroll'
const rawData = [
{
user: '王*',
phone: '159****0121',
depart: '松北',
orgName: '移动',
time: '',
},
{
user: '张*',
phone: '136****9980',
depart: '保定阜平综合驻点',
orgName: '铁塔',
time: '',
},
{
user: '莫**',
phone: '159****0990',
depart: '联通业务维护',
orgName: '联通',
time: '',
},
{
user: '李*',
phone: '138****4988',
depart: '铁岭市区驻点',
orgName: '电信',
time: '',
},
]
const data1 = [...rawData, ...rawData]
const Index: React.FC = () => {
const [data] = useState(() => {
return data1.map((item, index) => {
const time = moment(
new Date().getTime() -
1000 * 60 * 60 * 1.5 + // 一小时前
(-1 + Math.random() * 2) * 1000 * 60 * 60 * 0.7 // 0.7小时内
).format('HH:mm:ss')
return {
...item,
id: index,
time,
}
})
})
const scrollResult = useBigScreenScroll({
data,
itemHeight: '46px',
})
return (
<div className={styles.container}>
<Item user="工程师" phone="号码" depart="所属组织" orgName="运营商" time="接单时间" />
<div className={styles.table_content}>
<div className={styles.item_wrap} style={scrollResult.divStyle}>
{scrollResult.scrollData.map((item, index) => {
return <Item key={item.id} {...item} />
})}
</div>
</div>
</div>
)
}
export default Index
效果
代码
import { useInterval } from 'ahooks'
import { CSSProperties, useEffect, useState } from 'react'
interface IUseBigScreenScrollOptions {
data?: any[]
itemHeight: number | string
transitionDuration?: number // 动画时长 ms
scrollInterval?: number // 滚动间隔 ms
judge?: () => boolean // 是否开启滚动 一般是判断当前数据的数量,如果数据量小于一屏就不滚动了
}
/**
* @description 一般是大屏用的,table无限滚动的hooks
* 注:scrollInterval要大于transitionDuration
*/
export default function useBigScreenScroll(options: IUseBigScreenScrollOptions): {
scrollData: any[]
divStyle: CSSProperties // 给list外层div设置的样式
} {
const { data = [], itemHeight, transitionDuration = 500, scrollInterval = 2000, judge } = options
const [data1, setData1] = useState<any[]>(data) // data1 是hooks内部保存的data
const [divStyle, setDivStyle] = useState<CSSProperties>({})
// 静止状态
const style1: CSSProperties = {
transition: 'none',
transform: 'translateY(0px)',
}
// 滚动状态
const style2: CSSProperties = {
transition: `all ${(transitionDuration * 100) / 1000 / 100}s`,
transform: `translateY(-${itemHeight})`,
}
useEffect(() => {
if (data.length > 0) {
setData1(data)
}
}, [JSON.stringify(data)])
useInterval(() => {
if (
data.length > 0 && //
(!judge || (judge && judge()))
) {
setDivStyle(style2)
setTimeout(() => {
setDivStyle(style1)
// 把第一个元素放到最后
const nextData1 = [...data1]
const first = {
...nextData1[0],
}
nextData1.shift()
nextData1.push(first)
setData1(nextData1)
}, transitionDuration + 6)
}
}, scrollInterval)
return {
scrollData: data1,
divStyle,
}
}