面试题答案
一键面试设计
- HTML 结构:
- 创建折叠面板的基本 HTML 结构,例如:
<div class="accordion"> <button class="accordion__toggle">Toggle</button> <div class="accordion__content"> <!-- 折叠面板内容 --> </div> </div>
- CSS 类设计:
- 基本样式:
- 定义
.accordion__content
的初始状态为隐藏,例如:
.accordion__content { display: none; opacity: 0; height: 0; overflow: hidden; transition: all 0.3s ease; /* 通用过渡 */ }
- 定义
- 展开样式:
- 创建一个类(如
.accordion__content--open
)来表示展开状态,设置显示、高度、不透明度等属性:
.accordion__content--open { display: block; opacity: 1; height: auto; }
- 创建一个类(如
- 特殊动画过渡:
- 例如在展开过程中内容逐渐填充,可以使用
clip - path
属性结合过渡。假设从顶部向下填充,首先定义一个初始的clip - path
值,如clip - path: polygon(0 0, 100% 0, 100% 0, 0 0);
,表示一个空的矩形(仅顶部一条线)。 - 在展开状态下,设置
clip - path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
,表示完整的矩形。 - 然后在过渡中包含
clip - path
的过渡:
.accordion__content { clip - path: polygon(0 0, 100% 0, 100% 0, 0 0); transition: all 0.3s ease, clip - path 0.5s ease; } .accordion__content--open { clip - path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }
- 例如在展开过程中内容逐渐填充,可以使用
- 基本样式:
实现
- JavaScript 交互:
- 使用
addEventListener
监听按钮的点击事件,例如:
const toggleButton = document.querySelector('.accordion__toggle'); const content = document.querySelector('.accordion__content'); toggleButton.addEventListener('click', () => { content.classList.toggle('accordion__content--open'); });
- 使用
- 处理过渡效果冲突:
- 避免多次触发过渡:
- 可以设置一个标志变量,例如:
let isTransitioning = false; toggleButton.addEventListener('click', () => { if (isTransitioning) return; isTransitioning = true; content.classList.toggle('accordion__content--open'); content.addEventListener('transitionend', () => { isTransitioning = false; }, { once: true }); });
- 与 JavaScript 控制的样式变化同步:
- 如果在 JavaScript 中改变了一些影响过渡的样式(如高度、不透明度等),确保在过渡开始前设置好初始值,并且在过渡结束后再进行后续的 JavaScript 操作。例如,如果在展开时需要动态加载内容,先触发过渡,然后在
transitionend
事件中进行内容加载:
toggleButton.addEventListener('click', () => { content.classList.add('accordion__content--open'); content.addEventListener('transitionend', () => { // 这里进行内容加载等后续操作 }, { once: true }); });
- 如果在 JavaScript 中改变了一些影响过渡的样式(如高度、不透明度等),确保在过渡开始前设置好初始值,并且在过渡结束后再进行后续的 JavaScript 操作。例如,如果在展开时需要动态加载内容,先触发过渡,然后在
- 避免多次触发过渡:
性能优化
- 减少重排和重绘:
- 合并样式修改:尽量一次性修改多个样式,而不是多次单独修改。例如,不要这样:
content.style.height = 'auto'; content.style.opacity = '1';
- 而是使用类名切换,让浏览器批量处理样式变化:
content.classList.add('accordion__content--open');
- 选择合适的过渡属性:
- 避免过渡过多的属性,只过渡那些视觉上必要的属性,如
opacity
、transform
等,因为这些属性触发的重排和重绘较少。例如,使用transform: scaleY(1)
代替直接修改高度来实现展开效果,这样可以利用 GPU 加速:
.accordion__content { transform: scaleY(0); transform - origin: top; transition: transform 0.3s ease; } .accordion__content--open { transform: scaleY(1); }
- 避免过渡过多的属性,只过渡那些视觉上必要的属性,如
- 硬件加速:
- 对于复杂的动画过渡,利用
will - change
属性提前告知浏览器即将发生的变化,让浏览器有机会提前进行优化,例如:
.accordion__content { will - change: transform; }
- 对于复杂的动画过渡,利用