当我们打开和关闭侧边栏时,通常会使用此动画。打开侧边栏可将其从左向右滑动。
布局
整个页面分为两部分,侧边栏和主要内容:
<div class="container">
<div class="sidebar">...</div>
<div class="content">...</div>
</div>
这是一个常见的布局,可以使用 CSS flexbox 进行存档:
.container {
display: flex;
}
.sidebar {
/* The initial width of sidebar */
width: 30%;
}
.content {
/* Take the available width */
flex: 1;
}
切换按钮有点有趣,需要更多的努力。当侧边栏滑动时,它会移动,因此它应该绝对定位在侧边栏上:
<div class="sidebar">
<div class="sidebar__content"></div>
<button class="sidebar__toggle">...</button>
</div>
.sidebar {
position: relative;
}
.sidebar__toggle {
/* Absolute position */
position: absolute;
top: 0;
right: 0;
transform: translate(100%, 0);
/* Size */
height: 2rem;
width: 2rem;
}
动画
我们必须为两种可能的动画准备 CSS 类。第一个名为 slide-out 类从右向左滑出侧边栏:
.slide-out {
animation-duration: 400ms;
animation-name: slide-out;
}
@keyframes slide-out {
0% {
transform: translateX(0%);
opacity: 1;
}
100% {
transform: translateX(-100%);
opacity: 0;
}
}
另一个行为相反,使侧边栏回到相反的方向:
.slide-in {
animation-duration: 400ms;
animation-name: slide-in;
}
@keyframes slide-in {
0% {
transform: translateX(-100%);
opacity: 0;
}
100% {
transform: translateX(0%);
opacity: 1;
}
}
管理动画类
在切换按钮 click 事件的处理程序中,我们将根据侧边栏是否展开来切换动画类。
let isExpanded = true;
const handleToggle = () => {
if (isExpanded) {
sidebarEle.classList.remove('slide-in');
sidebarEle.classList.add('slide-out');
} else {
sidebarEle.classList.remove('slide-out');
sidebarEle.classList.add('slide-in');
}
isExpanded = !isExpanded;
};
toggleButtonEle.addEventListener('click', () => {
handleToggle();
});
上面的示例代码很容易理解,只要我们用 toggleButtonEle and sidebarEle 变量表示切换按钮和侧边栏。我们还需要 isExpanded 标志来跟踪侧边栏展开状态。
默认情况下,该 isExpanded 标志设置为 true 。以下是用户首次单击切换按钮时的步骤:
- 侧边栏元素删除类
slide-out - 侧边栏元素添加
slide-in类 - 反转
isExpanded标志
结果,侧边栏确实是动画的。但是,它不会从容器中消失。实际上,动画完成后它会飞回原来的形状。
为了解决这个问题,我们将侧边栏的宽度设置为零。设置它的正确时机是动画完成其工作时。
sidebarEle.addEventListener('animationend', (e) => {
if (e.target === sidebarEle) {
sidebarEle.classList.remove('slide-in');
sidebarEle.classList.remove('slide-out');
if (!isExpanded) {
sidebarEle.classList.add('sidebar--collapsed');
}
}
});
当元素的子元素完全动画化时,animationend 将触发该事件。因此,您可以看到检查 e.target === sidebarEle 确保我们处理的是侧边栏的动画事件,而不是其子项。
根据标志的不同 isExpanded ,侧边栏将附加宽度为零的折叠变体:
.sidebar--collapsed {
width: 0;
}