场景
点击收起时ul-wrapper高度设置为100px,展开时高度设置为auto,同时设置展开,收起的动画transition: all 3s; 但是动画不生效
const App = () => {
const [expand, setExpand] = useState(false);
return (
<div>
<div onClick={
() => setExpand(!expand)}>{
expand ? '收起' : '展开'}</div>
<ul className="ul-wrapper" style={
{
height: expand ? 'auto' : '100px' }}>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
</ul>
</div>
);
};
.ul-wrapper {
margin-top: 20px;
height: 100px;
width: 200px;
overflow: hidden;
border: 1px solid red;
transition: all 3s;
li {
height: 50px;
}
}
解决
必须设置height为一个具体值时transition动画才会生效,但是ul-wrapper中的数据需要动态渲染,并不知道展开后的准确高度!通过套一个父盒子,并在父盒子上设置max-height来实现transition动画,展开后的高度通过js动态获取
- 子盒子ul-wrapper不设置高度,动态撑开
- 父盒子ul-wrapper-parent的max-height根据expand值动态设置,超出部分隐藏 overflow: hidden; 同时设置transition动画
此时,由于ul-wrapper-parent展开,收起时的max-height都是具体值,展开动画生效
const Block = () => {
const [expand, setExpand] = useState(false);
useEffect(() => {
const parent = document.getElementById('parent');
const child = document.getElementById('child');
if (!parent) return;
if (expand && child) {
parent.style.maxHeight = child.getBoundingClientRect().height + 'px';
} else {
parent.style.maxHeight = '100px';
}
}, [expand]);
return (
<div>
<div onClick={
() => setExpand(!expand)}>{
expand ? '收起' : '展开'}</div>
<div className="ul-wrapper-parent" id="parent">
<ul className="ul-wrapper" id="child">
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
<li>数据啦啦啦...</li>
</ul>
</div>
</div>
);
};
.ul-wrapper-parent {
max-height: 100px;
overflow: hidden;
transition: all 3s;
margin-top: 20px;
width: 200px;
overflow: hidden;
border: 1px solid red;
.ul-wrapper {
li {
height: 50px;
}
}
}
文章评论