通过使用React库 react-transition-group
的 Transition
来实现对未知高度的元素进行展开收缩动画过渡效果实现。
1. 安装 react-transition-group
npm install react-transition-group --save
or
pnpm add react-transition-group
2. 使用 Transition
实现
属性介绍
-
in
:
表示元素是否处于进入状态或离开状态。如果为 true,则表示元素处于进入状态,反之,则表示元素处于离开状态。 -
timeout
:
表示动画执行的时间。可以设置为数字,也可以设置为对象,分别表示进入和离开动画的执行时间。 -
appear
:
表示是否在组件首次挂载时执行进入动画。如果为 true,则表示首次挂载时会执行进入动画。 -
mountOnEnter
:
表示在进入动画开始时,组件需要挂载到 DOM 上。 -
unmountOnExit
:
表示在离开动画结束时,组件需要从 DOM 上卸载。
Transition 事件介绍:
react-transition-group 的 Transition 组件提供了一些事件,可以让我们在动画执行过程中执行一些自定义操作。以下是一些 Transition 组件提供的事件:
-
onEnter(node: HTMLElement, isAppearing: boolean)
:
在元素进入动画开始之前触发,可以在此时对元素进行一些自定义的操作。 -
onEntering(node: HTMLElement, isAppearing: boolean)
:
在元素进入动画执行中触发,可以在此时对元素进行一些自定义的操作。 -
onEntered(node: HTMLElement, isAppearing: boolean)
:
在元素进入动画完成之后触发,可以在此时对元素进行一些自定义的操作。 -
onExit(node: HTMLElement)
:
在元素离开动画开始之前触发,可以在此时对元素进行一些自定义的操作。 -
onExiting(node: HTMLElement)
:
在元素离开动画执行中触发,可以在此时对元素进行一些自定义的操作。 -
onExited(node: HTMLElement)
:
在元素离开动画完成之后触发,可以在此时对元素进行一些自定义的操作。
实现代码
const AA = () => {
const [isOpen, setIsOpen] = useState(false);
const onClick = () => {
setIsOpen((open) => !open);
};
const onEnter = (el) => {
el.style.transition = '0.3s max-height ease';
el.style.maxHeight = '0px';
el.style.overflow = 'hidden';
};
const onEntering = (el) => {
el.style.maxHeight = el.scrollHeight + 'px';
};
const onEntered = (el) => {
el.style.transition = '';
el.style.maxHeight = '';
};
const onExit = (el) => {
el.style.overflow = 'hidden';
el.style.maxHeight = el.scrollHeight + 'px';
};
const onExiting = (el) => {
if (el.scrollHeight !== 0) {
el.style.transition = '0.3s max-height ease';
el.style.maxHeight = '0px';
}
};
const onExited = (el) => {
el.style.transition = '';
el.style.maxHeight = '';
};
return (
<div>
<button type="button" onClick={onClick}>
{isOpen ? '收起' : '展开'}
</button>
<Transition in={isOpen} timeout={300} unmountOnExit onEnter={onEnter} onEntering={onEntering} onEntered={onEntered} onExit={onExit} onExiting={onExiting} onExited={onExited}>
<div style={{ width: 200 }}>
这是内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
</div>
</Transition>
</div>
);
};