React.js-使用滑入式滑出动画将一个div过渡到另一个div

时间:2019-03-28 03:56:46

标签: css reactjs

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

我的问题是我不知道如何将javascript和CSS捆绑在一起。当我单击按钮并触发事件时,我不确定如何开始动画。

反应

DECLARE @xmlTable TABLE ([Value] XML)
INSERT INTO
    @xmlTable
VALUES
    ('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <HCNSearchResponse xmlns="http://testurl.com/">
      <HCNSearchResult>
        <HCNLookupResult>
          <MsgID>test1</MsgID>
          <Results>
            <DemographicDetails>
              <Title>Ms</Title>
              <Forename1>F1 test</Forename1>
              <Forename2 />
              <Forename3>F3 test</Forename3>
              <Sex>F</Sex>
              <DateOfBirth>01/01/2000</DateOfBirth>
              <Surname>test1</Surname>
            </DemographicDetails>
            <DemographicDetails>
              <Title>Mr</Title>
              <Forename1>F1 test</Forename1>
              <Forename2 />
              <Forename3></Forename3>
              <Sex>M</Sex>
              <DateOfBirth>01/01/2000</DateOfBirth>
              <Surname>test2</Surname>
            </DemographicDetails>
          </Results>
        </HCNLookupResult>
      </HCNSearchResult>
    </HCNSearchResponse>
  </soap:Body>
</soap:Envelope>')

SELECT
    [Value].query(
        'declare namespace soap = "http://schemas.xmlsoap.org/soap/envelope/"
        ;declare default element namespace "http://testurl.com/"
        ;/soap:Envelope/soap:Body/HCNSearchResponse/HCNSearchResult/HCNLookupResult/Results')
FROM
    @xmlTable

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); 

2 个答案:

答案 0 :(得分:0)

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

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

我也将动画从一个transformx更改为一个left属性,将其设置为left: -100px,然后将动画设置为left: 0

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

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

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

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

实际上,我再次更新了代码,因为有一个问题,如果您在滑动发生时单击蓝页,则会抛出动画,因为它在动画完成之前会更新类,因此您需要跟踪滑动是否发生发生时,在完成所有动画之前,您不允许点击操作: 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;
}

答案 1 :(得分:0)

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

中测试代码

这是 React 代码(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;
}