问题:写字体轮播的时候,不使用swiper库,使用top定位,让字体过渡上下移动,发现写成的效果就是每次播到最后一个元素后,只能突然展示第一个元素,失去了那种上下移的动过渡效果。

解决:

import { useRef, useEffect, useState } from 'react';
import './index.scss';

const tsetData = Array.from({ length: 2 }, (_, i) => ({
    text: `测试元素${i + 1}`,
}));

const Swiper = () => {
    const [activeIndex, setActiveIndex] = useState(1);
    const viewRef1 = useRef() as any;
    const viewRef2 = useRef() as any;
    const topRef1 = useRef(0) as any;
    const topRef2 = useRef(0) as any;
    const timerRef = useRef() as any;

    useEffect(() => {
        viewRef2.current.innerHTML = viewRef1.current.innerHTML;
    }, []);

    useEffect(() => {
        // 轮播中每个元素的高度
        const viewHeight = viewRef1.current.scrollHeight / tsetData.length;

        if (tsetData.length > 1) {
            if (timerRef.current) {
                clearTimeout(timerRef.current);
            }
            timerRef.current = setTimeout(() => {
                // 第一个盒子元素在轮播第一个元素至倒数第二个元素
                if (topRef1.current <= 0 && viewHeight < viewRef1.current.scrollHeight + topRef1.current) {
                    topRef1.current -= viewHeight;
                    // 第二个盒子元素在下面候着
                    topRef2.current = viewHeight;
                    viewRef1.current.style.opacity = 1;
                    viewRef2.current.style.opacity = 0;
                } else if (topRef2.current <= 0 && viewHeight < viewRef2.current.scrollHeight + topRef2.current) {
                    // 第一个盒子元素在下面候着
                    topRef1.current = viewHeight;
                    topRef2.current -= viewHeight;
                    viewRef1.current.style.opacity = 0;
                    viewRef2.current.style.opacity = 1;
                } else {
                    topRef1.current -= viewHeight;
                    topRef2.current -= viewHeight;
                    viewRef1.current.style.opacity = 1;
                    viewRef2.current.style.opacity = 1;
                }
                viewRef1.current.style.top = `${topRef1.current}px`;
                viewRef2.current.style.top = `${topRef2.current}px`;
                // activeIndex可用于其他功能
                setActiveIndex(activeIndex === tsetData.length ? 1 : activeIndex + 1);
            }, 5000);
        }
    }, [activeIndex]);

    return (
        <div className="Swiper">
            <div className="Swiper-box" ref={viewRef1}>
                {tsetData.map((item, index) => (
                    <div className="Swiper-box-item" key={index}>
                        {item.text}
                    </div>
                ))}
            </div>
            <div className="Swiper-box Swiper-box2" ref={viewRef2}></div>
        </div>
    );
};

export default Swiper;

.Swiper {
    width: 750px;
    height: 100px;
    background-color: pink;
    overflow: hidden;
    position: relative;
}

.Swiper-box {
    width: 100%;
    height: 100px;
    color: #333333;
    position: absolute;
    top: 0px;
    transition: top .5s;
}

.Swiper-box2 {
    opacity: 0;
}

.Swiper-box-item {
    height: 100px;
    line-height: 100px;
    text-align: center;
}

最后效果:

视频

更多推荐