1、dom.style.width:DOM樹的內(nèi)聯(lián)樣式
直接讀取元素內(nèi)聯(lián)樣式屬性,僅反映 HTML 標(biāo)簽中 style 屬性定義的值,無法獲取外部CSS或內(nèi)嵌樣式表設(shè)置的寬度。
返回值特征:
- 僅返回內(nèi)聯(lián)樣式設(shè)置的寬度,未設(shè)置則返回空字符串
- 帶單位字符串(如"200px"),百分比設(shè)置則返回百分比字符串
- 不包含 padding、border 和 margin
關(guān)鍵特性: - 可通過
element.style.width = "300px"直接修改內(nèi)聯(lián)樣式 - 設(shè)置時(shí)必須指定單位(如px、em),否則無效
2、getComputedStyle(dom).width:CSSOM樹的計(jì)算結(jié)果
從 CSSOM 樹讀取計(jì)算后樣式值,反映所有CSS規(guī)則應(yīng)用后的最終寬度,包括外部樣式表、內(nèi)嵌樣式和繼承樣式。
返回值特征:
- 返回計(jì)算后的絕對值(如"200px"),無論CSS中設(shè)置的是百分比或em
- 不包含 border 和 margin
關(guān)鍵差異示例:
.box { width: 50%; }
<div class="box" style="width: 200px;"></div>
此時(shí) style.width 返回 "200px",而 getComputedStyle(box).width 返回計(jì)算后的像素值(如"512px",取決于父容器寬度)。
注意事項(xiàng):
- 只讀屬性,無法通過該方法修改樣式
- 每次調(diào)用重新計(jì)算,可能觸發(fā)重排
- IE8及以下需用 element.currentStyle 替代
3、dom.clientWidth:布局樹的可視內(nèi)容寬度
從瀏覽器布局樹讀取元素內(nèi)部可視寬度,代表布局引擎計(jì)算后的實(shí)際占用空間。
返回值特征:
- 數(shù)值類型(無單位),四舍五入為整數(shù)
- 不包含 border、margin 和 scroll
- 元素隱藏(display:none)則返回 0
計(jì)算邏輯: - 標(biāo)準(zhǔn)盒模型(content-box):
clientWidth = contentWidth + paddingLeft + paddingRight - 怪異盒模型(border-box):
clientWidth = contentWidth + paddingLeft + paddingRight + borderLeft + borderRight(此時(shí)CSS設(shè)置的width已包含這些值)
4、dom.getBoundingClientRect().width:視覺渲染的最終尺寸
返回元素在視口坐標(biāo)系中的視覺邊界矩形寬度,代表元素在屏幕上實(shí)際顯示的尺寸。
返回值特征:
- 浮點(diǎn)數(shù)值(精確到小數(shù)位)
- 包含內(nèi)容區(qū)域 + padding + border + scroll
- 受CSS變換(transform)影響,如
scale(1.5 )會使寬度擴(kuò)大1.5倍 - 相對于視口左上角計(jì)算,隨頁面滾動變化
注意事項(xiàng): - top、left 值隨頁面滾動變化,固定位置需加上 pageXOffset、pageYOffset
- 頻繁調(diào)用可能觸發(fā)重繪
- 元素有 border-radius 時(shí)仍返回矩形邊界
性能優(yōu)化
避免在動畫幀中頻繁調(diào)用 getBoundingClientRect 和 getComputedStyle,建議每幀緩存結(jié)果
批量讀取尺寸屬性,避免讀寫操作交替觸發(fā)多次重排
使用 requestAnimationFrame 控制讀取時(shí)機(jī),減少布局抖動
瀏覽器兼容
IE8及以下用 element.currentStyle 替代 getComputedStyle
低版本IE中 getBoundingClientRect 不包含 width/height 屬性,需通過 right/left 計(jì)算
移動端Android 4.4以下 clientWidth 可能包含滾動條寬度
精確測量
小數(shù)精度要求高的場景(如canvas繪圖)必須使用 getBoundingClientRect
測量隱藏元素尺寸時(shí),臨時(shí)設(shè)置 position: absolute; visibility: hidden 替代 display: none
響應(yīng)式布局中結(jié)合 resizeObserver 監(jiān)聽尺寸變化,而非定時(shí)查詢
總結(jié)
四個(gè)API對應(yīng)瀏覽器渲染流水線的不同階段:DOM樹(style.width)→ CSSOM樹(getComputedStyle)→ 布局樹(clientWidth)→ 渲染樹(getBoundingClientRect)。實(shí)際開發(fā)中需根據(jù)場景選擇。
- 樣式修改場景:dom.style.width,直接操作內(nèi)聯(lián)樣式
- 樣式查詢場景:getComputedStyle,獲取最終計(jì)算樣式
- 布局計(jì)算場景:clientWidth,獲取布局寬度用于排版
- 視覺交互場景:getBoundingClientRect,如拖拽、碰撞檢測
- 動畫場景:getBoundingClientRect().width,獲取精確浮點(diǎn)值