面试题答案
一键面试采用的CSS技术
- Flexbox:
- 适用场景:当元素的布局方向比较简单,例如水平或垂直排列,并且需要根据容器大小或其他元素动态调整自身大小时,Flexbox非常合适。比如一个导航栏,当窗口大小改变时,导航项需要自适应排列。
- 实现方式:通过设置
display: flex
将容器变为弹性容器,然后利用flex - grow
、flex - shrink
和flex - basis
属性来控制子元素的伸缩和基础尺寸。例如,若某个元素需要根据兄弟元素的减少而自动扩展宽度,可以设置flex - grow: 1
。
- Grid:
- 适用场景:对于复杂的二维布局,当需要精确控制元素在行列中的位置,并且元素的尺寸需要根据其他行列元素动态调整时,Grid布局很有用。比如一个电商产品展示页面,每个产品卡片的大小需要根据整个展示区域以及其他卡片的数量动态调整。
- 实现方式:通过设置
display: grid
将容器变为网格容器,利用grid - template - columns
和grid - template - rows
定义网格的列和行模板,通过grid - column
和grid - row
属性控制元素在网格中的位置。通过fr
单位(弹性分数单位)可以很方便地实现元素宽度和高度根据容器剩余空间动态分配,例如grid - template - columns: 1fr 2fr
,表示两列,第二列宽度是第一列的两倍,并且会根据容器宽度变化而自适应。
- JavaScript联动:
- 适用场景:当需要根据更复杂的业务逻辑或其他非直接CSS相关的条件来动态调整元素的宽度和高度时,JavaScript联动是必要的。例如,根据用户在页面上的特定操作(如点击按钮、滚动页面等)来改变某些元素的尺寸。
- 实现方式:通过
addEventListener
监听相应的事件,在事件处理函数中获取需要操作的元素,然后使用element.style.width
和element.style.height
来动态修改元素的宽度和高度。为了优化性能,尽量批量操作元素的样式,而不是多次单独修改。
避免重排(reflow)和重绘(repaint)的方法
- 样式改变方面:
- 使用
classList
:避免直接操作元素的style
属性,而是通过添加或移除class
来改变样式。例如,假设我们有一个.large - size
类定义了特定的width
和height
,当需要改变元素大小的时候,使用element.classList.add('large - size')
,这样浏览器可以预先计算好新样式的渲染,减少重排和重绘的次数。相比之下,多次直接操作element.style.width
会导致多次重排。 - 批量修改样式:如果确实需要直接操作
style
属性,将多个样式改变合并在一起执行。例如:
- 使用
const element = document.getElementById('my - element');
const newStyles = {
width: '200px',
height: '100px',
color: 'red'
};
const styleString = Object.entries(newStyles).map(([key, value]) => `${key}:${value}`).join(';');
element.style.cssText = styleString;
这样只触发一次重排和重绘,而不是每个样式改变都触发。 2. 布局计算方面:
- 使用
transform
和opacity
:当仅需要改变元素的位置(平移、旋转、缩放等)或透明度时,使用transform
和opacity
属性。这些属性的改变不会触发重排,只会触发重绘,因为它们不影响元素在文档流中的位置和布局。例如,将元素从一个位置移动到另一个位置,可以使用element.style.transform = 'translateX(50px)'
,而不是修改left
属性。 - 利用
will - change
:提前告知浏览器哪些属性可能会改变,让浏览器有机会提前优化。例如,element.style.will - change = 'width'
,表示即将改变元素的宽度,浏览器可能会提前分配资源,优化后续的布局和渲染过程。但要注意不要滥用,因为过多使用可能会占用额外的内存。