[React] 손글씨 가상화 무한 스크롤 구성 요소
27357 단어 React
전언
의 원리
스크롤 막대가 나타납니다.
가시 영역의 원활한 이동
플래시 화면 최적화
효과
코드
<Virtualize itemHeight={rootSize*(4.5596)} columnNumber={2}
insightNumber={6} startHeight={rootSize*6}
scrollDom={document.querySelector('.home-main-container')}
>
{
props.renderProduct.productList.map((item:Product,index:number)=>{
return (
<Link key={item.id} to={{pathname:`/productdetail/${item.id}`,state:item}}
>
<Card
hoverable
key={item.id}
cover={
<div data-src={item.poster}
className='list-item'
ref={(ref)=>{
if(ref){
io!.observe(ref)
}}}
>
<Icon type="picture"></Icon>
</div>
}
><Card.Meta title={item.title} description={` :${item.price} `} />
</Card>
</Link>
)
})
}
</Virtualize>
type Props = PropsWithChildren<{
itemHeight:number//
columnNumber:number//
insightNumber:number//
startHeight:number//
scrollDom:HTMLDivElement|null // dom
scaleRow?:number//
}>
function Virtualize(props:Props){
const [costomHeight,setCostomHeight]=useState()
const [visbleHeight,setVisibleHeight]=useState()
const [renderChildren,setRenderChildren]=useState()
const [indexNumber,setIndexNumber]=useState({
startIndex:0,
endIndex:props.insightNumber,
overScroll:0
})
const [scaleRow,setScaleRow]=useState(2)
useEffect(()=>{
if(props.children instanceof Array){
let childrenLen = props.children.length
if(childrenLen%props.columnNumber!=0){//
let remain = childrenLen%props.columnNumber
childrenLen=childrenLen+remain
}
let fullheight = childrenLen/props.columnNumber*props.itemHeight
setCostomHeight(fullheight)
let insightHeight
if(childrenLen<props.insightNumber){
insightHeight = fullheight
}else{
insightHeight = props.insightNumber/props.columnNumber*props.itemHeight
}
setVisibleHeight(insightHeight)
setRenderChildren(props.children.slice(indexNumber.startIndex,indexNumber.endIndex))
}
},[props.children,indexNumber])
const scrollFunc=(e:Event)=>{
let target= e.target as HTMLDivElement
let overScroll = target.scrollTop-props.startHeight//
let timer = overScroll/props.itemHeight*props.columnNumber
let startIndex =Math.floor(timer)// 0
startIndex = startIndex<0?0:startIndex;
timer = timer%props.columnNumber/props.columnNumber//
if(timer<0)timer=0;
if(overScroll<0)overScroll=0
if(startIndex%props.columnNumber!=0){//
startIndex=startIndex-startIndex%props.columnNumber
}
let endIndex = startIndex+props.insightNumber+scaleRow
overScroll=overScroll-timer*props.itemHeight
setTimeout(() => {
setIndexNumber({
startIndex,
endIndex,
overScroll
})
});
}
useEffect(()=>{
props.scaleRow?setScaleRow(props.scaleRow):null;
if(props.scrollDom)
props.scrollDom.addEventListener('scroll',throttle(scrollFunc,50))
return ()=>{
if(props.scrollDom)
props.scrollDom.removeEventListener('scroll',throttle(scrollFunc,50))
}
},[])
return (
<>
<div style={{display:'flex'}}>
<div style={{height:costomHeight?costomHeight:0,backgroundColor:'red',width:'20px'}} ></div>
<div className='virtual-custom-item'
style={{
height:visbleHeight?visbleHeight:0,
position:"relative",
transform:`translate3d(0px, ${indexNumber.overScroll}px, 0px)`
}}>
{renderChildren}
</div>
</div>
</>
)
}
export default Virtualize
넓히다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
바삭바삭하고 간단한 결제 페이지 만들기먼저 Next.js에서 프로젝트를 만듭니다. Vercel & Next.js가 매우 편하기 때문에 최근에는이 구성을 사용하고 있습니다. 그런 다음 Tailwind CSS를 넣습니다. Tailwind CSS를 사용하면 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.