创建一个在react中工作的加载动画

Create a loading animation that works in react

本文关键字:工作 加载 动画 react 一个 创建      更新时间:2023-09-26

Fiddle

var Hello = React.createClass({
    getInitialState: function() {    
    return {
      gridIsLoaded: true
      }
  },
  animate(self) {    
    console.log('animating...');
    $('#loadingDiv').animate({'opacity': '0'}, 500, function(){
      $('#loadingDiv').animate({'opacity': '.5'}, 500, function(){
          $('#loadingDiv').animate({'opacity': '1'}, 500, function(){
            //if(!self.state.gridIsLoaded){
              self.animate();
            //}
          });
      });
    });
  },
  getData() {
    console.log('getData called.');    
    var artificialTimeout = 5000;
    var self = this;
    self.animate(self);
    $.ajax({
        url:'/echo/js/?js=hello%20world!',
        complete: function (response) {
            console.log(response.responseText);
            setTimeout(function() {
                  self.setState({gridIsLoaded: true});
              }, artificialTimeout);
        },
        error: function () {
            console.log('there was an error!');
            self.setState({gridIsLoaded: true});
        },
    });
    return false;
    },  
  handleClick(){
    console.log('handleClick');
    this.getData();
    this.setState({gridIsLoaded: false});
  },
  render: function() {
    var loadingJsx;
    if (!this.state.gridIsLoaded) {
      loadingJsx = (
          <div id="loadingDiv" style={{ position:'relative', 'width': '100%', 'textAlign': 'center'}} className="text-center">
              Loading... please wait
          </div>);
    };
    return <div>
        {loadingJsx}
      <div>
            <input type="button" value="Submit" onClick={this.handleClick} />      
      </div>
    </div>;
  }
});
ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

当我点击提交时,上面写着"正在加载,请稍候…"。我希望在显示加载时,不透明度可以设置动画。这是行不通的。然后,如果我再次点击提交,它也会做同样的事情。

我怎样才能使动画发挥作用?

简单的案例外部反应工作。

实现这一点的一种更"反应"的方法是,当你想为元素设置动画时,在元素上切换一个类。因此,在这种情况下,我们可以在网格尚未加载时有条件地应用一个animate类(尽管在这种情况中它是多余的,因为这是它唯一显示的时间)。

loadingJsx = (
  <div id="loadingDiv" className={this.state.gridIsLoaded ? 'text-center' : 'text-center animate'}>
    Loading... please wait
  </div>);

然后,我将css分离出来应用于#loadingDiv.animate,不过另一种方法是切换样式对象。我想你也可以不断更新样式对象的不透明度属性,这更接近你正在做的事情,但它看起来更脏。

#loadingDiv.animate {
  opacity: 0;
  animation: fadeInOut 1s infinite;
}
@keyframes fadeInOut {
  0% { opacity: 0; }
  50% { opacity: 1; }
  100% { opacity: 0; }
}

更新的fiddle