# 位置

  • clientWidthoffsetWidthscrollWidth
  • clientHeightoffsetHeightscrollHeight
  • clientTopoffsetTopscrollTop
  • clientLeftoffsetLeftscrollLeft
  • clientXoffsetXpageXscrentX
  • clientYoffsetYpageYscrentY

以上元素、鼠标事件对象的属性,很容易混淆。下面用图文进行解释。

WARNING

如果当前元素的visibility: hidden;生效,那么依然可以取得上述值。如果当前元素的display: none;生效,那么以上的值都为 0。

# clientWidth、clientHeight

ClientWH

// 可视窗口宽度 + 左右padding之和 - 右侧滚动条的宽度
clientWidth = vContentW + paddingX - scrollW;
// 可视窗口高度 + 上下padding之和 - 底部滚动条的高度
clientHeight = vContentH + paddingY - scrollH;
1
2
3
4

# offsetWidth、offsetHeight

!OffsetWH

// 可视窗口宽度 + 左右padding之和 + 左右边框之和
offsetWidth = vContentW + paddingX + borderW;
// 可视窗口高度 + 上下padding之和 + 上下边框之和
offsetHeight = vContentH + paddingY + borderH;
1
2
3
4

# scrollWidth、scrollHeight

ScrollWH

// 自身左右padding之和 + 自身内容宽度(不分是否可视)
scrollWidth = paddingX + contentW;
// 自身上下padding之和 + 自身内容高度(不分是否可视)
scrollHeight = paddingY + contentH;
1
2
3
4

TIP

如果没有出现滚动条,也就是自身内容就是可视窗口。意味clientWidth === scrollWidthclientHeight === scrollHeight

# clientTop、clientLeft

ClientLT

其实就是自身的border的宽度、高度。

// 上边框的高度
clientTop = borderH;
// 左边框的宽度
clientLeft = borderW;
1
2
3
4

# offsetTop、offsetLeft

OffsetLT

  • 对于块状元素:相对与上个偏移容器el.offsetParent来计算的。从自身的border外侧到上个定位容器的border内侧的距离。包含自身的topleft距离。
  • 对于行内元素:相对与上个偏移容器el.offsetParent来计算的。从自身的border外侧到上个定位容器的border外侧的距离。包含自身的topleft距离。

偏移容器一般是设置过position: absolute | fixed | relative | sticky。如果祖父级都没有设置过,那么默认是el.offsetParent=body,而body.offsetParent=null

// 元素到body的纵向距离(累加方式)
export function offsetTop(el) {
  let value = el.offsetTop;
  while (el.offsetParent) {
    el = el.offsetParent;
    value += el.offsetTop;
  }
  return value;
}
1
2
3
4
5
6
7
8
9

WARNING

自身的transform: translate(x, y)不算,虽然看上去是偏移了,但实际上 DOM 位置不变,只是视觉效果进行了偏移。

# scrollTop、scrollLeft

ScrollLT

滚动了多少距离,也是children被卷去的宽度和高度。children的边界到自己的padding的内侧算起。

TIP

获取页面滚动距离使用document.documentElement.scrollTop,部分浏览器使用document.body.scrollTop的值依旧是 0。比如:谷歌浏览器。

# clientX、clientY

XY

  • clientX: 当前鼠标位置到浏览器可视窗口左上角横向距离
  • clientY: 当前鼠标位置到浏览器可视窗口左上角纵向距离

# offsetX、offsetY

  • offsetX: 当前鼠标位置到该元素左上角的 boder 内侧横向距离
  • offsetY: 当前鼠标位置到该元素左上角的 boder 内侧纵向距离

TIP

该元素就是添加监听事件的 DOM。

# pageX、pageY

  • pageX: 当前鼠标位置到文档左上角横向距离,可以看成clientX加上文档的横向滚动距离
  • pageY: 当前鼠标位置到文档左上角纵向距离,可以看成clientY加上文档的纵向滚动距离
pageX = clientX + document.documentElement.scrollLeft;
pageY = clientY + document.documentElement.scrollTop;
1
2

# screntX、screenY

  • screntX: 当前鼠标位置到用户屏幕(显示器)横向距离。
  • screenY: 当前鼠标位置到用户屏幕(显示器)纵向距离。