getBoundingClientRect与transform的兼容
先说结论
getBoundingClientRect
会受到 transform
的影响,比如你的元素设置了 transform:scale(2)
,那么 getBoundingClientRect
返回的 width
会是元素实际宽度的2倍,top
等位置信息也会因为元素尺寸变化而发生变化。
起因
产品中有一个需求,要实现页面的缩放功能,考虑到兼容性就没有使用 zoom
(火狐不支持),而是使用了 transfrom
的 scale
。
在页面缩放的时候,组件在计算截断宽度的时候出现了问题,导致如图:
根据代码排查,组件在计算宽度的时候,使用 getBoundingClientRect
:
这里就不对 getBoundingClientRect
做过多的描述了,通过下图能看到一些注意事项:
至于组件之前为啥用 getBoundingClientRect
就不得而知了。
在修改之前也对比了这两种计算方式得出的宽高:
- getBoundingClientRect:该方法返回的
DOMRect
对象中的width
和height
属性是包含了padding
和border-width
的,而不仅仅是内容部分的宽度和高度。在标准盒子模型中,这两个属性值分别与元素的width/height + padding + border-width
相等。而如果是box-sizing: border-box
,两个属性则直接与元素的width
或height
相等。 - offsetWidth:offsetWidth 是测量包含元素的边框 (border)、水平线上的内边距 (padding)、竖直方向滚动条 (scrollbar)(如果存在的话)、以及 CSS 设置的宽度 (width) 的值。
然后查了下性能相关,貌似问题也不大:
《What forces layout / reflow》:https://gist.github.com/paulirish/5d52fb081b3570c81e3a
结尾
文章到这里,差不多就没啥好说的了,考虑到组件的通用性,在使用 getBoundingClientRect
前确保有没有缩放的需求,如果有缩放需求,那就尽量避免吧……
paypal.me 链接失效了
链接更新了;)