代码之家  ›  专栏  ›  技术社区  ›  user2924127

Reactjs-使用滑入滑出动画将一个div转换为另一个div

  •  1
  • user2924127  · 技术社区  · 7 年前

    我有一页有两个div。每个div占据整个屏幕,因此一个div在开始时在顶部可见,而另一个不可见。当我单击第一个div上的按钮时,我希望第二个div滑入并在第一个div顶部可见。然后我希望第二个div滑出并再次显示第一个div。

    我的问题是我不知道如何将javascript和css结合起来。当我点击按钮并触发事件时,我不确定如何启动动画。

    反应

    const styles = {
      p1: "page1",
      p2: "page2",  
      slideIn: "slideIn",      
    }
    
    
    class App extends Component {
    
      constructor(props) {
        super(props);
    
        this.state = {
        }
    
        this.handleClick = this.handleClick.bind(this);
    
    } 
    
      handleClick = () => {
    
        //Make Page 2 slide in and then slide out
        //Apply the class page2Visible to make page 2 visible
    
      };
    
      render() {
    
        const { classes } = this.props;
    
    
        return (
    
    <React.Fragment>
        <div className={`${styles.p1}`} onClick={this.handleClick}>Page 1</div>
        <div className={`${styles.p2} ${styles.slideIn}`}>Page 2</div>
      </React.Fragment>
        );
    
      }
    
    }
    
    export default withStyles(styles)(App); 
    

    CSS

    .App {
      margin: 0;
      padding: 0;
    }
    
    .page1 {
    
      background-color: blue;
        margin:0;
        padding:0;
        z-index:8;
        top:0;
        left:0; 
        position:fixed;
        width:100%;
        height:100%;  
    
    }
    
    .page2 {
    
      background-color: red;
      margin:0;
      padding:0;
      z-index:8;
      top:0;
      left:0; 
      position:fixed;
      width:100%;
      height:100%;  
        opacity: 0;
        transform: translateX(-100%);
        -webkit-transform: translateX(-100%);
    }
    
    .slideIn {
      animation: slide-in 0.5s forwards;
      -webkit-animation: slide-in 0.5s forwards;
    }
    
    .slideOut {
      animation: slide-out 0.5s forwards;
      -webkit-animation: slide-out 0.5s forwards;
    }
    
    @keyframes slideIn {
      100% { transform: translateX(0%); }
    }
    
    @-webkit-keyframes slideIn {
      100% { -webkit-transform: translateX(0%); }
    }
    
    @keyframes slideOut {
      0% { transform: translateX(0%); }
      100% { transform: translateX(-100%); }
    }
    
    @-webkit-keyframes slideOut {
      0% { -webkit-transform: translateX(0%); }
      100% { -webkit-transform: translateX(-100%); }
    }
    
    
    .page2Visible {
    
      visibility: visible;
      opacity: 1;
    }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Krishna Uppili    7 年前

    最初,您必须维护当前活动div的状态。单击每个div时都有一个按钮隐藏该特定div并使另一个div处于活动状态。在下面给出的示例代码中,我给出了div的高度为500px,但您可以根据需要提供高度。这是我用的 轻松进出 transition属性来执行向上滑动和向下滑动动画。您可以在中测试代码 https://jsfiddle.net/krishnauppili/okn4vbe0/5/

    这是答案 反应 代码(App.js):

    class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            activeDiv: "div1",
        }
    }
    
    toggleDiv = () => {
        this.setState({
            activeDiv: this.state.activeDiv === "div1" ? "div2" : "div1",
        });
    };
    
    render() {
        return (
            <div className="App">
                <div className={this.state.activeDiv === "div1" ? "div1 show" : "div1 hide"} id="div1">
                    Div 1
                    <button type="button" onClick={this.toggleDiv}> Hide div1</button>
                </div>
                <div className={this.state.activeDiv === "div2" ? "div2 show" : "div2 hide"} id="div2">
                    Div 2
                    <button type="button" onClick={this.toggleDiv}> Hide div2</button>
                </div>
            </div>
        );
    }}
    

    这是答案 CSS 代码(App.css):

    .div1{
        background-color: black;
    }
    .div2{
        background-color: green;
    }
    .div1,.div2{
        color:white;
    }
    .div1.show,.div2.show{
        height:500px;
        transition:  all 0.2s ease-in-out;
        padding-top: 50px;
        text-align: center;
    }
    .div1.hide,.div2.hide{
        text-align: center;
        height: 0;
        overflow: hidden;
        transition: all 0.2s ease-in-out;
    }
    
        2
  •  0
  •   Abdul Ahmad    7 年前

    你有几个问题,首先你必须在你的状态下存储你的动画类,并在点击蓝色框时更新你的状态。此外,动画和关键帧标识符的拼写也不一致:

    将动画设置为 animation: slide-in 而关键帧标识符是“slideIn”,注意一个是camelcase,另一个有破折号。我将您的代码复制到JSFIDLE中,必须: https://jsfiddle.net/ahmadabdul3/y6xsveL5/22/

    我还将动画从translatex更改为left属性,设置为 left: -100px 动画将其设置为 left: 0

    我更新了JSFIDLE,让第2页滑入,等待2秒钟,然后滑出。我使用了setState回调函数,将超时设置为2秒,然后将类从slideIn设置为slideOut: https://jsfiddle.net/ahmadabdul3/y6xsveL5/29/

    然后在大约600毫秒后,我将类重置为没有额外滑动类的原始状态。这样,如果再次单击,它将再次滑动

    我不确定setState回调是否是正确的解决方案,我认为有一种方法可以从css定制动画,使其在滑入后滑出。

    如果您希望在单击第2页时将其滑出,可以复制第1页的handle click方法,只需将类更改为slide out

    实际上,我再次更新了代码,因为出现了一个问题,如果在滑动过程中单击蓝色页面,它会抛出动画,因为它会在动画完成之前更新类,您需要跟踪滑动是否发生,在所有动画完成之前,您不允许单击执行任何操作: https://jsfiddle.net/ahmadabdul3/y6xsveL5/35/

    最终代码:

    class TodoApp extends React.Component {
      sliding = false;
      state = {
        page2Class: "",     
      };
    
      handleClick = () => {
        if (this.sliding) return;
        this.sliding = true;
        this.setState({ page2Class: 'slideIn' }, () => {
          setTimeout(() => {
            this.setState({ page2Class: 'in-view slideOut' }, () => {
              setTimeout(() => {
                this.setState({ page2Class: '' }, () => {
                  this.sliding = false;
                });
              }, 600)
            });
          }, 2000)
        });
      };
    
      render() {
        const { page2Class } = this.state;
        return (
          <div>
            <div className='page1' onClick={this.handleClick}>Page 1</div>
            <div className={`page2 ${page2Class}`}>Page 2</div>
          </div>
        )
      }
    }
    

    css

    .App {
      margin: 0;
      padding: 0;
    }
    
    .page1 {
      background-color: blue;
      margin:0;
      padding:0;
      z-index:8;
      top:0;
      left:0; 
      position:fixed;
      width:100%;
      height:100%;  
    }
    
    .page2 {
      background-color: red;
      margin:0;
      padding:0;
      z-index:8;
      top:0;
      left:-100%; 
      position:fixed;
      width:100%;
      height:100%;  
    }
    
    .in-view {
      left: 0;
    }
    
    .slideIn {
      animation: slideIn 0.5s forwards;
      -webkit-animation: slideIn 0.5s forwards;
    }
    
    .slideOut {
      animation: slideOut 0.5s forwards;
      -webkit-animation: slideOut 0.5s forwards;
    }
    
    @keyframes slideIn {
      100% { left: 0; }
    }
    
    @-webkit-keyframes slideIn {
      100% { left: 0; }
    }
    
    @keyframes slideOut {
      100% { left: 100%; }
    }
    
    @-webkit-keyframes slideOut {
      100% { left: 100%; }
    }
    
    
    .page2Visible {
      visibility: visible;
      opacity: 1;
    }