【问题标题】:React make a full-page CarouselReact 制作整页轮播
【发布时间】:2022-08-14 00:36:55
【问题描述】:

我正在尝试制作一个从 div 的子元素从左到右滚动的动画,我环顾四周,但其他有答案的问题似乎都不起作用,到目前为止,这就是我所完成的:

主页.css:

@keyframes scroll {
    20% {
        transform: translateX(-100vw);
    }

    40% {
        transform: translateX(-200vw);
    }

    60% {
        transform: translateX(-300vw);
    }

    80% {
        transform: translateX(-400vw);
    }

    100% {
        transform: translateX(0vw);
    }
}

.section {
    display: flex;
    flex-direction: row;
    font-family: Arial, sans-serif;
    font-weight: bold;
    transition: 1s;
    width: 100vw;
    height: 100vh;
    animation-name: scroll;
    animation-duration: 1s;
}

.child1 {
    background-color: #c0392b;
    flex: none;
    width: 100vw;
    height: 100vh;
}

.child2 {
    background-color: #e67e22;
    flex: none;
    width: 100vw;
    height: 100vh;
}

.child3 {
    background-color: #27ae60;
    flex: none;
    width: 100vw;
    height: 100vh;
}

.child4 {
    background-color: #2980b9;
    flex: none;
    width: 100vw;
    height: 100vh;
}

.child5 {
    background-color: #8e44ad;
    flex: none;
    width: 100vw;
    height: 100vh;
}

主页.jsx:

import { forwardRef, useEffect, useRef, useState } from \"react\";
import { Link } from \"react-router-dom\";
import \'./Home.css\';

const Child1 = forwardRef((props, ref) => {
    return <div className=\"child1\">
        <h1>Child1</h1>
    </div>;
});

const Child2 = forwardRef((props, ref) => {
    return <div className=\"child2\">
        <h1>Child2</h1>
    </div>;
});

const Child3 = forwardRef((props, ref) => {
    return <div className=\"child3\">
        <h1>Child3</h1>
    </div>;
});

const Child4 = forwardRef((props, ref) => {
    return <div className=\"child4\">
        <h1>Child4</h1>
    </div>;
});

const Child5 = forwardRef((props, ref) => {
    return <div className=\"child5\">
        <h1>Child5</h1>
    </div>;
});

function Home() {

    let section = useRef();
    let [currentSection, setCurrentSection] = useState(0);

    useEffect(() => {
        window.addEventListener(\"keypress\", (event) => {
            if(event.key === \"d\") {
                // scroll right (play animation forwards by one step)
            } else if(event.key === \"a\") {
                // scroll left (play animation backwards by one step)
            }
        });
    });

    return <div ref={section} className=\"section\">
        <Child1></Child1>
        <Child2></Child2>
        <Child3></Child3>
        <Child4></Child4>
        <Child5></Child5>
    </div>
}

export default Home;

问题是动画从一开始就播放,我想不出只有在触发键盘事件时才播放它的方法,如果 event.key 是“a”,那么元素应该向左滚动,否则如果 event.key 是“d”,则元素应向右滚动。

Here 是 CodeSandbox 的链接。

    标签: html css reactjs events jsx


    【解决方案1】:

    该解决方案与您的示例紧密耦合,但从我的角度来看,您可以使其更通用。

    我没有使用CSS 动画,而是使用scrollTo 方法来实现滚动行为。

    主页.jsx

    import { forwardRef, useEffect, useRef, useState } from "react";
    import "./styles.css";
    
    //  I not using forwardRef and ref at all
    const Child1 = forwardRef((props, ref) => {
      return (
        <div className="child1">
          <h1>Child1</h1>
        </div>
      );
    });
    
    const Child2 = forwardRef((props, ref) => {
      return (
        <div className="child2">
          <h1>Child2</h1>
        </div>
      );
    });
    
    const Child3 = forwardRef((props, ref) => {
      return (
        <div className="child3">
          <h1>Child3</h1>
        </div>
      );
    });
    
    const Child4 = forwardRef((props, ref) => {
      return (
        <div className="child4">
          <h1>Child4</h1>
        </div>
      );
    });
    
    const Child5 = forwardRef((props, ref) => {
      return (
        <div className="child5">
          <h1>Child5</h1>
        </div>
      );
    });
    
    function App() {
      let section = useRef();
      let [currentSection, setCurrentSection] = useState(0);
    
      const handler = (event) => {
        if (event.key === "d") {
          if (currentSection === 4) {
            setCurrentSection(0);
            return;
          }
          setCurrentSection((prev) => prev + 1);
        } else if (event.key === "a") {
          if (currentSection === 0) return;
          setCurrentSection((prev) => prev - 1);
        }
      };
    
      useEffect(() => {
        window.addEventListener("keypress", handler);
    
        // you should clean up you EventListener
        return () => {
          window.removeEventListener("keypress", handler);
        };
      }, [handler]);
    
      useEffect(() => {
        window.scrollTo({
          behavior: "smooth",
          left: window.innerWidth * currentSection,
          top: 0,
        });
      }, [currentSection]);
    
      return (
        <div ref={section} className="section">
          <Child1></Child1>
          <Child2></Child2>
          <Child3></Child3>
          <Child4></Child4>
          <Child5></Child5>
        </div>
      );
    }
    
    export default App;
    

    主页.css

    .section {
        display: flex;
        flex-direction: row;
        font-family: Arial, sans-serif;
        font-weight: bold;
        transition: 1s;
        width: 100vw;
        height: 100vh;
    }
    
    .child1 {
        background-color: #c0392b;
        flex: none;
        width: 100vw;
        height: 100vh;
    }
    
    .child2 {
        background-color: #e67e22;
        flex: none;
        width: 100vw;
        height: 100vh;
    }
    
    .child3 {
        background-color: #27ae60;
        flex: none;
        width: 100vw;
        height: 100vh;
    }
    
    .child4 {
        background-color: #2980b9;
        flex: none;
        width: 100vw;
        height: 100vh;
    }
    
    .child5 {
        background-color: #8e44ad;
        flex: none;
        width: 100vw;
        height: 100vh;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-15
      • 1970-01-01
      • 1970-01-01
      • 2017-05-02
      • 2022-10-19
      • 2021-09-15
      • 2022-09-23
      • 2023-03-12
      相关资源
      最近更新 更多