我正在开发一个React小部件(逐步向导),该小部件可从API获取并显示内容。我不知道我从API提取的文本有多长时间。所以我不知道小部件的高度。小部件应增加与内容有关的高度(例如默认的HTML元素)。不应滚动。
我无法在此处设置固定高度。因此,我无法为要设置动画的幻灯片设置position: absolute
。
目前,动画如下所示:
第二张幻灯片出现在第一张幻灯片的下方,直到第一张幻灯片消失并且第二张幻灯片向上移动。当然,这完全是丑陋的。
如果我为幻灯片设置了固定的高度和绝对位置,那么一切都将正常且平滑。
您可以在此处查看我的问题的演示:https://codepen.io/anon/pen/jdQPRw
最佳答案
TransitionGroup应该包装多个Transition或CSSTransition
因此,首先您应该将每张幻灯片包装在CSSTransition中。
第二个让“ in”属性处理组件的“ hide&show”
<CSSTransition in={slide === 2}
然后在动画完成后使用属性unmountOnExit来卸载幻灯片
我已经分叉了您的笔并对其进行了编辑,它正在工作,请检查更改
https://codepen.io/anon/pen/yZZqKo
const { TransitionGroup, CSSTransition } = ReactTransitionGroup;
class Slide extends React.Component {
render() {
return <div
className="slide"
style={{backgroundColor: this.props.bg}}
>{this.props.content}</div>
}
}
const content1 = 'Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. ';
const content2 = 'Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. Demo Text with different Length. This will get fetched from API. ';
class Widget extends React.Component {
state = { slide: 1 }
render() {
const slide = this.state.slide;
return (
<div className="widget">
<TransitionGroup className="wrapper"><div>
<CSSTransition
in={slide === 1}
classNames="fade"
timeout={{ enter: 500, exit: 0 }}
appear
unmountOnExit
><Slide content={ content1 } bg="#fafafa" />
</CSSTransition></div><div>
<CSSTransition
in={slide === 2}
classNames="fade"
timeout={{ enter: 500, exit: 0 }}
appear
unmountOnExit
><Slide content={ content2 } bg="#ccc" />
</CSSTransition></div>
</TransitionGroup>
<div className="buttons">
<button
className="next"
onClick={ () => this.setState({slide: 1})}
>Slide 1</button>
<button
className="next"
onClick={ () => this.setState({slide: 2})}
>Slide 2</button>
</div>
</div>
);
}
}
ReactDOM.render(
<Widget />,
document.getElementById('root')
);
body {
background: #eee;
}
.page {
max-width: 500px;
margin: 30px auto;
}
.widget {
padding: 20px;
background: #fff;
border-radius: 5px;
overflow: hidden;
}
.slide {
padding: 20px;
border-radius: 3px;
}
.buttons {
display: flex;
}
.next {
display: flex;
flex: 1;
margin: 10px;
background: blue;
color: #fff;
padding: 14px;
margin-top: 10px;
border: 0;
border-radius: 3px;
font-size: 20px;
text-decoration: none;
text-align: center;
}
.fade-enter {
opacity: 0.01;
}
.fade-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
.fade-enter-done {opacity:1}
.fade-exit {
opacity: 1;
}
.fade-exit-active {
opacity: 0.01;
transition: opacity 500ms ease-in;
}
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-transition-group/2.5.3/react-transition-group.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/4.3.1/react-router-dom.js"></script>
<div class="page">
<h1>Content</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ullamcorper ac tortor quis vulputate. Cras commodo dolor quis odio rutrum accumsan. Vestibulum aliquam bibendum odio vel auctor. In feugiat elit ac accumsan posuere. Donec facilisis tellus vitae faucibus pharetra. Aenean arcu dolor, molestie ut cursus vitae, congue id tortor. In scelerisque scelerisque dolor eget laoreet. Donec et consequat quam. Maecenas suscipit quis mi ac luctus. Aliquam aliquet vitae erat ut ultricies. Suspendisse laoreet lacinia nisl sit amet facilisis. Aliquam ac lorem leo. Etiam feugiat sagittis erat eget ullamcorper. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<div id="root">
<!-- This element's contents will be replaced with your component. -->
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ullamcorper ac tortor quis vulputate. Cras commodo dolor quis odio rutrum accumsan. Vestibulum aliquam bibendum odio vel auctor. In feugiat elit ac accumsan posuere. Donec facilisis tellus vitae faucibus pharetra. Aenean arcu dolor, molestie ut cursus vitae, congue id tortor. In scelerisque scelerisque dolor eget laoreet. Donec et consequat quam. Maecenas suscipit quis mi ac luctus. Aliquam aliquet vitae erat ut ultricies. Suspendisse laoreet lacinia nisl sit amet facilisis. Aliquam ac lorem leo. Etiam feugiat sagittis erat eget ullamcorper. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>