javaScript

react 实现一个多列轮播

2020-06-09  本文已影响0人  反者道之动001

效果

实现思路

代码

html

<div className="flex select-wrap" ref={containerRef}>
                    <div className="flex" style={{width: '100%', transform: `translateX(${translateX})`, transition: 'transform 500ms'}}>
                        {list.map((item, i) => <div className={'swiper-slide item' + ((i == num) ? ' active' : '')} style={{width: itemWidth + 'px'}}>
                            <img src={item.img} className="img" />
                        </div>)}
                    </div>
                </div>

js

let containerRef = useRef(null)
    const list = responseStudentVoiceList
    const [num, setnum] = useState(0)
    const [translateX, settranslateX] = useState('0px')
    const slidesPerView = 7
    const [itemWidth, setitemWidth] = useState(0)
    const [totalWidth, settotalWidth] = useState(0)
    
    const slideTo = (num: number, type: string) => {
        // translateX值
        const left = +(translateX.replace('px', ''))
        let width = (num) * itemWidth
        
        // 右侧边界处
        if(type == 'right' && Math.abs(((width % totalWidth) / itemWidth) + (left / itemWidth) % slidesPerView) == 0){
            let _n = list.length - num
            let n = _n > slidesPerView ? slidesPerView : _n
            let v = - (itemWidth * n)
            settranslateX(`${v + left}px`)
        }
        // 左侧边界
        if(type == 'left' && Math.abs(width) == Math.abs(left)){
            settranslateX(`${num > slidesPerView ? left - (-totalWidth) : 0}px`)
        }
    }
    const onLeft = () => {
        if (num <= 0) return 
        setnum(num - 1)
        slideTo(num , 'left')
    }
    const onRight = () => {
        if (num >= list.length - 1) return 
        setnum(num + 1)
        slideTo(num + 1, 'right')
    }
    useEffect(() => {
        const totalWidth = +getComputedStyle(containerRef.current).width.replace('px', '')
        settotalWidth(totalWidth)
        setitemWidth(totalWidth / slidesPerView)
    }, [])

--end--

上一篇下一篇

猜你喜欢

热点阅读