一、DOM 宽高
API 比较
注:content 宽度 不一定等于 CSS 声明的 width 值,依据 box-sizing 值有不同。
| 方法 | 返回值 | 描述 | 读写能力 |
|---|---|---|---|
Element.style.width | string(带设置单位),如果用户设置的是非法值,则返回空字符串。 | 显式地通过style.width写入的string值 | 可读写 |
🌟 Element.offsetWidth | 整数型 number(小于 0.25 舍去,大于0.25进一),单位 px | 标准盒模型:width + padding + borderIE 盒模型: width | 只读 |
Element.clientWidth | 整数型 number(小于 0.25 舍去,大于0.25进一),单位 px | 标准盒模型:width + paddingIE 盒模型: contentinline 元素值为 0 | 只读 |
Element.scrollWidth | 整数型 number(小于 0.25 舍去,大于0.25进一),单位 px | 元素内容高度的度量,包括由于溢出导致的视图中不可见内容。 也包括 ::before 和 ::after这样的伪元素。 | 只读 |
window.getComputedStyle(element).width | 计算值或应用值,带 'px' 的 string | 标准盒模型:widthIE 盒模型: width | 只读(强制赋值报错) |
Element.getBoundingClientRect.width | actual value 实际渲染值,浮点型 number,单位 px | 标准盒模型:width + padding + border IE 盒模型: width | 只读 |
DOM 元素 heigth 的获取也是相同的道理。
兼容性
所有方法放心使用,不必担心兼容性问题,其他如currentStyle等非标准属性就不做过多介绍。
clientHeight、offsetHeight兼容IE6以上
Element.getBoundingClientRect 兼容IE9以上浏览器
window.getComputedStyle 兼容IE9以上浏览器
经验
在实际开发中,因为clientWidth,offsetWidth获取的值会进行四舍五入,当数量多了就会累积误差,导致出现bug,在这个时候就可以使用getComputedStyle()或者更高精度的getBoundingClientRect()以获取实际渲染值。
二、指针坐标
指针坐标包含触控点坐标,鼠标坐标。可使用 MouseEvent、TouchEvent、PointerEvent 这三种事件获取。
API 比较
| 属性 | 返回值 | 描述 |
|---|---|---|
event.clientX | number | 以浏览器窗口左边为原点,不论 Page 是否横向滚动。 |
event.x | number | event.clientX的别名。 |
event.pageX | number | 以 Page 左边为原点,考虑 Page 的滚动 |
event.screenX | number | 以用户显示器左边为原点,如果水平方向多屏联动,也计算在内。 |
event.offsetX | number | 事件对象与目标节点的内填充边(即以 padding 外边为起点)在 X 轴方向上的偏移量。 |
event.layerX | number | 非标准,事件对象与目标节点的 border 边(以 border 外边为起点)在 X 轴方向上的偏移量。 |
event.movementX | 整数型 number | 它提供了当前事件和上一个 mousemove 事件之间鼠标在水平方向上的移动值。换句话说,这个值是这样计算的 : currentEvent.movementX = currentEvent.screenX - previousEvent.screenX无论是指针还是鼠标事件,返回都是整数型 number,所以精度很差。 |
MouseEvent vs TouchEvent vs PointerEvent
比较:
- 返回值精度,
MouseEvent返回整数,TouchEvent和PointerEvent返回浮点数。 PointerEvent更通用但兼容性偏差 Safari 13 才支持,无论是何种触控方式,TouchEvent只适用于触摸操作,不适用于鼠标操作。
三、其他 API
offsetLeft/offsetTop
HTMLElement.offsetLeft是一个只读属性,返回当前元素左上角相对于HTMLElement.offsetParent节点的左边界偏移的像素值。HTMLElement.offsetLeft是从HTMLElement.offsetParent的padding边界开始计算的(不包括offsetParent的border)。
clientLeft/clientTop
- 在标准盒子模型中,
clientWidth=width+padding; clientLeft是当前元素的剩下的border-left的宽度;- 不过在 IE 盒模型中,
clientLeft不变,依然等于border-left的宽度。