首页>demo12

Demo12 - 动画 by zuojj at 02 Jul 2016

本例中实现动画时需注意,需要使用react-with-addons.js替换前面实例中引入的react.js,并初始化var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;,同时需要设置transitionName来对应CSS中的动画类,transitionEnterTimeouttransitionLeaveTimeout来指定动画timeout

HTML

<div id="animation" class="animation"></div>

CSS

.animation {
    width: 300px;
    margin: 0 auto;
    padding: 10px;

    border: 1px solid #ccc;
    border-radius: 3px;
}

.filter {
    display: flex;
}
.filter-text {
    line-height: 30px;

    height: 30px;
    padding: 0;

    border: 1px solid #ccc;
    border-radius: 3px;

    flex: 1;
}
.filter-btn {
    line-height: 32px;

    width: 60px;
    height: 32px;
    margin-left: 10px;

    cursor: pointer;

    border: 1px solid #ccc;
    border-radius: 3px;
    background: none;
}
.olist {
    margin: 10px 0 0;
    padding-left: 0;

    list-style: none;

    border: 1px dotted #ccc;
}
.olist li {
    line-height: 30px;

    display: flex;

    padding: 0 5px;

    border-bottom: 1px dotted #ccc;
    background-color: #efefef;
}
.olist li:last-child {
    border: none;
}
.olist li .content {
    flex: 1;
}
.btn-remove {
    line-height: 24px;

    display: inline-block;

    width: 60px;
    height: 24px;
    margin-top: 3px;

    cursor: pointer;
    text-align: center;

    border-radius: 3px;
    background-color: #ccc;
}

.fade-enter {
    -webkit-animation-duration: .5s;
            animation-duration: .5s;
    -webkit-animation-play-state: paused;
            animation-play-state: paused;
    -webkit-animation-timing-function: cubic-bezier(.55, 0, .55, .2);
            animation-timing-function: cubic-bezier(.55, 0, .55, .2);

    opacity: 0;

    -webkit-animation-fill-mode: both;
            animation-fill-mode: both;
}
.fade-appear {
    -webkit-animation-duration: .5s;
            animation-duration: .5s;
    -webkit-animation-play-state: paused;
            animation-play-state: paused;
    -webkit-animation-timing-function: cubic-bezier(.55, 0, .55, .2);
            animation-timing-function: cubic-bezier(.55, 0, .55, .2);

    opacity: 0;

    -webkit-animation-fill-mode: both;
            animation-fill-mode: both;
}
.fade-leave {
    -webkit-animation-duration: .5s;
            animation-duration: .5s;
    -webkit-animation-play-state: paused;
            animation-play-state: paused;
    -webkit-animation-timing-function: cubic-bezier(.55, 0, .55, .2);
            animation-timing-function: cubic-bezier(.55, 0, .55, .2);

    -webkit-animation-fill-mode: both;
            animation-fill-mode: both;
}
.fade-enter.fade-enter-active {
    -webkit-animation-name: fadeIn;
            animation-name: fadeIn;
    -webkit-animation-play-state: running;
            animation-play-state: running;
}
.fade-appear.fade-appear-active {
    -webkit-animation-name: fadeIn;
            animation-name: fadeIn;
    -webkit-animation-play-state: running;
            animation-play-state: running;
}
.fade-leave.fade-leave-active {
    -webkit-animation-name: fadeOut;
            animation-name: fadeOut;
    -webkit-animation-play-state: running;
            animation-play-state: running;
}
@-webkit-keyframes fadeIn {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
@keyframes fadeIn {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
@-webkit-keyframes fadeOut {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}
@keyframes fadeOut {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

JAVASCRIPT

var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;

var TodoList = React.createClass({
    getInitialState: function() {
        return {
            items: ['Benjamin']
        }
    },
    handleAdd: function() {
        var value = this.refs.username.value,
            _items = this.state.items;

        if(!value) {
            alert('请填写用户名称');
            return;
        }
        if(_items.includes && _items.includes(value)) {
            alert('已存在该项!');
            return;
        }

        this.setState({
            items: _items.concat(value)
        })
    },
    handleRemove: function(index) {
        var _items = this.state.items;

        _items.splice(index, 1);

        this.setState({
            items: _items
        });
    },
    render: function() {
        var _items = this.state.items.map(function(item, index) {
            return (
                <li key={index}>
                    <span className="content">{item}</span>
                    <span className="btn-remove" onClick={this.handleRemove.bind(this,index)}>delete</span>
                </li>
            );
        }.bind(this));

        return (
            <div>
                <div className="filter">
                    <input className="filter-text" type="text" placeholder="请输入用户名" ref="username" />
                    <input className="filter-btn" type="button" value="Add" onClick={this.handleAdd} />
                </div>
                <ol className="olist">
                    <ReactCSSTransitionGroup  transitionEnterTimeout={500} transitionLeaveTimeout={500} transitionName="fade">
                        {_items}
                    </ReactCSSTransitionGroup>
                </ol>
            </div>
        );
    }
});

ReactDOM.render(<TodoList/>, document.getElementById('animation'));