使用React.js的slideUp()和slideDown()动画

时间:2016-06-07 10:38:26

标签: javascript jquery reactjs

我创建了一个react组件,它由slideUp()和slideDown()动画组成。我使用jQuery slideup和slidedown方法实现了。

我必须使用反应动画实现此功能。

我读到了 ReactTransitionGroup ReactCSSTransitionGroup 。解释的方式告诉我,当 DomNode 挂载到组件或卸载时,我们可以执行此功能(如果我错了,请纠正我)。

我的问题是 - >如何以反应方式执行slideup()和slidedown()而不使用jQuery。

请参阅此{jsFiddle https://jsfiddle.net/guc3yrm1/

P.S - >请解释一下,为什么这个反应动画部分与jQuery相比似乎有点困难(我是一个jQuery人)

var Hello = React.createClass({
    getInitialState: function() {
        return {
            slide: false,
        }
    },
    slide: function() {
        if (this.state.slide) {
            $(this.refs.slide).slideDown();
            this.setState({
                slide: false
            });
        } else {
            $(this.refs.slide).slideUp();
            this.setState({
                slide: true
            });
        }
    },
    render: function() {
        return ( 
            <div>
                <input type = "button" value = "clickme" onClick = {this.slide}/> 
                <br />
                <br />
                <div className = "slide" ref="slide" >< /div>
            </div>
        );
    }
});

ReactDOM.render( < Hello name = "World" / > ,
    document.getElementById('container')
);

3 个答案:

答案 0 :(得分:30)

您可以在两个动画的API中实现动画。这是主要的区别:

  

ReactTransitionGroup是ReactCSSTransitionGroup所在的API   建成。两者之间的主要区别在于   ReactTransitionGroup动画是用Javascript编写的,而不是   提供CSS,并在动画时调用回调   完成而不是依赖CSS过渡事件。

我的结论是使用CSS动画来完成简单的任务,而Javascript则用于复杂的任务。

例如,如果组件具有静态高度 - 您可以通过CSS实现它,如下面的示例所示。但如果宽度/高度是动态的,那么你可以用Javascript来做。在Javascript示例中,我使用Velocity库来制作动画。 It's performance better than jQuery's animations。当然你可以自己实现动画,但为什么要重新发明轮子?

我已经使用这两个API实现了slideUp / slideDown。请在下面查看。

(CSS)通过ReactCSSTransitionGroup实现:

const CSSTransitionGroup = React.addons.CSSTransitionGroup;
const TransitionGroup = React.addons.TransitionGroup;

class Example extends React.Component{
    constructor(props) {
        super(props);
        this.state = { visible: false };
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick() {
    	this.setState({ visible: ! this.state.visible });
    }

    render() {
        return <div>
            <button onClick={this.handleClick}>{this.state.visible ? 'Slide up' : 'Slide down'}</button>
            <CSSTransitionGroup transitionName="example">
            	{ this.state.visible ? <div className='panel' /> : null }
            </CSSTransitionGroup>
        </div>
    }
}

React.render(<Example />, document.getElementById('container'));
.panel {
    width: 200px;
    height: 100px;
    background: green;
    margin-top: 10px;
}

.example-enter {
    height: 0px;
}

.example-enter.example-enter-active {
    height: 100px;
    -webkit-transition: height .3s ease;
}

.example-leave.example-leave-active {
    height: 0px;
    -webkit-transition: height .3s ease;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

JSFiddle - React Slide up and Slide down animation - CSS Transtion Group

(Javascript)通过ReactTransitionGroup实现:

const TransitionGroup = React.addons.TransitionGroup;

class Example extends React.Component{
    constructor(props) {
        super(props);
        this.state = { visible: false };
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick() {
        this.setState({ visible: ! this.state.visible });
    }

    render() {
        return <div>
            <button onClick={this.handleClick}>{this.state.visible ? 'Slide up' : 'Slide down'}</button>
                <TransitionGroup>
                    { this.state.visible ? <Accordion /> : null }
                </TransitionGroup>
            </div>
        }
    }

    class Accordion extends React.Component {
        componentWillEnter (callback) {
            const element = this.container.getDOMNode();
            Velocity(element, 'slideDown', { duration: 300 }).then(callback);
        }

        componentWillLeave (callback) {
            const element = this.container.getDOMNode();
            Velocity(element, 'slideUp', { duration: 300 }).then(callback);
        }

        setContainer(c) {
            this.container = c;
        }

        render() {
            return <div className="panel" ref={this.setContainer.bind(this)}>
                Lorem Ipsum is simply dummy text of the printing and typesetting industry.
                Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
            </div>
        }
    }

React.render(<Example />, document.getElementById('container'));
.panel {
    background: green;
    margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.4.3/velocity.min.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

JSFiddle - React Slide up and Slide down animation - Javascript Transition group

现金:

答案 1 :(得分:4)

如果你(像我一样)来到这里寻找jQuery&#39; slideDown / slideUp的替代品,那么 react-slidedown 似乎易于使用的反应组分。它的github页面有演示示例代码

答案 2 :(得分:2)

根据Jordan Enev的要求,我分叉了他的JSFiddle。

这是一个不需要React Css Transition Group的解决方案。 我个人是班级切换的粉丝。那就是你可以创建css动画但是你喜欢它。

https://jsfiddle.net/fyuh32je/3/

(小提琴中的整个代码)

class Example extends React.Component{
    constructor(props) {
        super(props);
        this.state = { visible: 'panel' };
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick() {
        this.setState({ visible: this.state.visible == 'panel'? 'panel visible' : 'panel' });
    }

    render() {
        return <div>
            <button onClick={this.handleClick}>{!this.state.visible == 'panel' ? 'Slide up' : 'Slide down'}</button>
                <div className={this.state.visible}>
                <p>This is some dynamic content!</p>
                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
              </div>
        </div>
    }
}

React.render(<Example />, document.getElementById('container'));

我知道使用像这样的可见状态变量很脏,但我在工作并且没有太多时间来改变太多。请注意,我们使用visible类来为div容器切换动画。

一般来说。动态高度容器可以使用css中的max-height属性的hacky用法进行动画处理。