【问题标题】:slideUp() and slideDown() animation using React.js使用 React.js 的 slideUp() 和 slideDown() 动画
【发布时间】:2016-10-07 05:16:49
【问题描述】:

我创建了一个由 slideUp() 和 slideDown() 动画组成的反应组件。我已经使用 jQuery slideup 和 slidedown 方法实现了。

我必须使用反应动画来实现这个功能。

我了解了 ReactTransitionGroupReactCSSTransitionGroup。解释的方式告诉我,我们可以在 DomNode 安装到组件或卸载时执行此功能(如果我错了,请纠正我)。

我的问题是 --> 如何在不使用 jQuery 的情况下以反应方式进行 slideup() 和 slidedown()。

请参阅此 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')
);

【问题讨论】:

  • 只是好奇:你为什么不想在这里使用 jQuery?
  • @Chris 我可以在 jQuery 的帮助下做到这一点。我很好奇如何在 reactTransitionAPI 中为反应组件中的静态内容执行此操作。最终我们可以通过使用 react 方式避免不必要的重新渲染

标签: javascript jquery reactjs


【解决方案1】:

您可以在两个动画的 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.


学分:

【讨论】:

  • 如果面板没有固定高度怎么办?
  • .invisble {max-height: 0%;溢出:隐藏;} .visible{ 最大高度:100%; }
  • 嘿,在这种情况下,我们可以通过 Javascript - ReactTransitionGroup 来实现它。我已经更新了我的答案,并添加了带有 Velocity 的 Javascript 示例。
  • @noa-dev 你能分叉我的 JSFiddle 并通过 CSS 实现吗? jsfiddle.net/jordan_enev/xtbxk20g
  • @JordanEnev 在我的回复中分叉并提到了你 :)
【解决方案2】:

如果你(像我一样)来这里是为了寻找 jQuery 的 slideDown/slideUp 的 react 替代品,那么 react-slidedown 似乎是一个易于使用的 react 组件。它的 github 页面有 demoexample code

【讨论】:

    【解决方案3】:

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

    这是一个不需要 React Css 过渡组的解决方案。 我个人是班级切换的粉丝。那就是您可以随意创建 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'));
    

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

    一般来说。动态高度容器可以通过在 css 中使用 max-height 属性来设置动画。

    【讨论】:

    • 嘿,谢谢你的努力!实际上,一旦面板可见,您就在硬编码面板的高度值。这个想法是一切都是动态的,即面板的高度与面板的内容高度相关。请查看我的 Javascript 示例。同样使用 ReactCSSTransitionGroup 您可以跳过手动设置 css 类的名称。
    • 对不起,我忘了删除固定高度声明。我更新了我的 JS Fiddle。您可以清楚地看到容器对其内容的行为是动态的,并且在没有固定高度的情况下打开时是动画的。您可以测试并删除或添加几行文本。
    • 感谢您的解决方法!正如您已经提到的那样,这是一种有点骇人听闻的方式。您还必须手动处理 css 类名称。当然,我会更喜欢 React 制作动画的方式!感谢贡献!
    • @noa-dev 我怎样才能在下面的链接上调整你的逻辑,保留我现有的点击事件功能?我仍然是绿色的反应。请看:stackoverflow.com/questions/48692961/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    相关资源
    最近更新 更多