React-实现循环轮播

问题:写字体轮播的时候,不使用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;
}

最后效果:

视频

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啊啊啊~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值