在 React 上每 3 秒 change/shift 在 div 上按下 class 个名字

change/shift down class names on div for every 3 seconds on React

我想将 css classes 一个接一个地向下移动,例如,如果图像是 3 秒后的起点,则所有 classes 都应该向下移动并且最后 class 应该在顶部,这样它会在轮播中移动图像,我希望它有意义,我们将不胜感激任何帮助!

  <div>
    <div class="nextRightSecond"> </div>
    <div class="hideRight"> </div>
    <div class="hideLeft"> </div>
    <div class="prevLeftSecond"> </div>
    <div class="prev"> </div>
    <div class="selected"> </div>
    <div class="next"> </div>
  <div>

查看此实例中的移动轮播 https://twcinnovations.com/services/mobile-applications

编辑:这是我的起始代码,看起来像

import {BsArrowLeftCircle, BsArrowRightCircle} from 'react-icons/bs'
import { useEffect, useState } from "react


const ImageSlider = () => {
 
  return (
    <Section outerCustomClass="mb-20 mt-10">
      <div className="flex flex-col items-center gap-y-4 ">
        {/* images */}

        <div className="w-full h-fit">

          <div className="relative overflow-hidden w-full">

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 `}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/1.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 `}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/2.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72`}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/3.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 `}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/4.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 `}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/5.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 `}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/6.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 `}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/7.jpg" alt="" />
            </div>

          </div>
        </div>

        <div className="text-sea-base flex gap-x-4 w-20 md:w-40 cursor-pointer">
          <BsArrowLeftCircle size={50} />
          <BsArrowRightCircle size={50} />
        </div>

我打算像这样创建一个没有任何 npm 包或依赖项的移动响应图像滑块。


按照以下步骤操作,并仔细参考下面的代码

  1. 创建一个对象,可以为每个图像存储 tailwind classes(或 css class 名称)。我创建了 7 种样式,因为为了制作无限滑块,来自左侧和右侧图像的第一个 img 都被隐藏了。

  2. 在顶部我定义了一个初始值为 0 的 sliderIndex 变量,每 3000 秒我们将其值增加 1(这与每 3000 秒按下一个按钮相同),使用 setInterval js 函数

  3. 当 sliderIndex 值更改时,每个图像从 classes 对象获得不同的样式,(请参阅每个图像 ${styleValues[(sliderIndex + 0) % styleValues.length] 上的 属性)在第一次迭代在下一次迭代中它将像 0,1,2,3,4,5,6 它将从 1,2,3,4,5,6,0 开始 在下一次它将是 2,3,4,5 ,6,1,2 所以每个获得这些 classes 的图像都会根据我们使用样式对象提供的样式自行放置它们。

这就是制作不带任何包的滑块所要做的全部, 我使用左、右 css 属性来移动图像和然后才弄明白 transform 属性 更适合这个任务所以如果你想要更好的性能可以使用它。

import {BsArrowLeftCircle, BsArrowRightCircle} from 'react-icons/bs'
import { useEffect, useState } from "react


const ImageSlider = () => {
  const [sliderIndex, setSliderIndex] = useState(0)

  const classes = {
    hideLeft: "opacity-0 -left-1/4 ",
    first:    "opacity-0 scale-100 | md:-left-1/4 | lg:left-0 lg:opacity-100",
    prev:     "-translate-x-full opacity-0 scale-100 | md:left-0 md:opacity-100 md:-translate-x-0 | lg:opacity-100 lg:left-1/3 lg:-translate-x-3/4 ",
    selected: "z-20 left-0 md:scale-110 md:left-1/2 md:-translate-x-1/2",
    next:     "z-20 scale-100 left-full -translate-x-full | md:z-10 md:left-full md:-translate-x-full | lg:opacity-100 lg:left-2/3 lg:-translate-x-1/4",
    last:     "scale-100 left-full | lg:opacity-100 lg:-translate-x-full ",
    hideRight:"opacity-0 left-full w-0"
  }

  const styleValues = Object.values(classes)

  const handleNextClick = () => {
    setSliderIndex((prev) => prev + 1)
  }

  const handlePreviousClick = () => {
    setSliderIndex((prev) => prev - 1)
  }

  useEffect(() => {
      const interval = setInterval(() => {
        handleNextClick()
      }, 3000)
      return () => clearInterval(interval)
    },[]
  )

  return (
    <Section outerCustomClass="mb-20 mt-10">
      <div className="flex flex-col items-center gap-y-4 ">
        {/* images */}

        <div className="w-full h-fit">

          <div className="relative overflow-hidden w-full">

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 ${styleValues[(sliderIndex + 0) % styleValues.length]} `}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/1.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 ${styleValues[(sliderIndex + 1) % styleValues.length]} `}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/2.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 ${styleValues[(sliderIndex + 2 ) % styleValues.length]}`}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/3.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 ${styleValues[(sliderIndex + 3) % styleValues.length]}`}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/4.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 ${styleValues[(sliderIndex + 4) % styleValues.length]}`}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/5.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 ${styleValues[(sliderIndex + 5) % styleValues.length]}`}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/6.jpg" alt="" />
            </div>

            <div className={`absolute top-1/2 -translate-y-1/2 w-40 md:w-44 xl:w-48 2xl:w-72 ${styleValues[(sliderIndex + 6) % styleValues.length]} `}>
              <img className="rounded h-96 w-80 object-contain" src="/images/common/slider/7.jpg" alt="" />
            </div>

          </div>
        </div>

        <div className="text-sea-base flex gap-x-4 w-20 md:w-40 cursor-pointer">
          <BsArrowLeftCircle size={50} onClick={handlePreviousClick}  />
          <BsArrowRightCircle size={50} onClick={handleNextClick} />
        </div>