10、JS 获取各种距离的方法有哪些?

屏幕相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// macOS 全屏模式下 的 window.screen
window.screen = {
availHeight: 950, // 可用高度,屏幕高度 - 系统上/下任务栏高度(若有)
availLeft: 0, // 系统左/右任务栏宽度
availTop: 32, // 系统上/下任务栏高度
availWidth: 1512, // 可用宽度,屏幕宽度 - 系统左/右任务栏宽度(若有)
height: 982, // ⭐️ 屏幕高度:availHeight + availTop
width: 1512, // ⭐️ 屏幕宽度:availWidth + availLeft
};

// 浏览器窗口左上角 与 屏幕左边 的距离,macOS 全屏模式下为 0
window.screenLeft === window.screenX;

// 浏览器窗口左上角 与 屏幕顶部 的距离,macOS 全屏模式下为 37
window.screenTop === window.screenY;

浏览器相关

1
2
3
4
5
6
7
8
window.outerWidth; // 浏览器的宽度
window.outerHeight; // 浏览器的高度

// ⭐️ 浏览器的可视区域的宽度(仅由视口大小决定),包含滚动条,等同于 100vh
window.innerWidth;

// ⭐️ 浏览器的可视区域的高度(仅由视口大小决定),包含滚动条,等同于 100vw
window.innerHeight;

网页相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// ⭐️ 浏览器可视区域的宽度(仅由视口大小决定),不包含滚动条
// 始终等于 window.innerWidth - 竖向滚动条宽度(若有)
document.documentElement.clientWidth

// ⭐️ 浏览器可视区域的高度(仅由视口大小决定),不包含滚动条
// 始终等于 window.innerHeight - 横向滚动条高度(若有)
document.documentElement.clientHeight

// html 元素的实际宽度(由自身样式或内容宽度决定),不包含滚动条
// 未设置样式时,默认为 100%,并等于 document.documentElement.clientWidth
// 若内容宽度大于 100%,则为内容宽度(即横向滚动条长度)
document.documentElement.scrollWidth

// html 元素的实际高度(由自身样式或内容高度决定),不包含滚动条
// 未设置样式时,默认为 100%,并等于 document.documentElement.clientHeight
// 若内容高度大于 100%,则为内容高度(即竖向滚动条高度)
document.documentElement.scrollHeight

// html 元素的竖向滚动条,已滚动的距离
document.documentElement.scrollTop

// html 元素的横向滚动条,已滚动的距离
document.documentElement.scrollLeft

元素相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 某个元素可视区域的宽度(仅由自身样式决定),不包含滚动条、padding、border
// 未设置样式时,默认为 100%,小于等于 父元素.clientWidth
// 若有自身样式,则为样式宽度
document.某个元素.clientWidth

// 某个元素的实际高度(由自身样式或内容高度决定),不包含滚动条
// 未设置样式时,默认为 0px
// 若内容高度大于 0,则为内容高度
// 若有自身样式,则为样式高度
document.某个元素.clientHeight

// 某个元素的实际宽度(由自身样式或内容宽度决定),不包含滚动条
// 未设置样式时,默认为 100%,并等于 该元素.clientWidth
// 若内容宽度大于 100%,则为内容宽度(即横向滚动条长度)
// 若有自身样式,则为 Max(内容宽度, 样式宽度)
document.某个元素.scrollWidth

// 某个元素的实际高度(由自身样式或内容高度决定),不包含滚动条
// 未设置样式时,默认为 0px
// 若内容高度大于 0,则为内容高度(即竖向滚动条高度)
// 若有自身样式,则为 Max(内容高度, 样式高度)
document.某个元素.scrollHeight

// 某个元素的竖向滚动条,已滚动的距离
document.某个元素.scrollTop

// 某个元素的横向滚动条,已滚动的距离
document.某个元素.scrollLeft

document.某个元素.offsetWidth // 等价于 某个元素.clientWidth + padding + border
document.某个元素.offsetHeight // 等价于 某个元素.clientHeight + padding + border
document.某个元素.offsetLeft // 自身左边 与最近的 offsetParent(默认为 body)的左边距离
document.某个元素.offsetTop // 自身上边 与最近的 offsetParent(默认为 body)的上边距离

举个🌰

1
2
3
4
5
6
7
8
9
10
11
12
<div id="example">
...Text...
</div>
<style>
#example {
width: 300px;
height: 200px;
border: 25px solid #E8C48F;
padding: 20px;
overflow: auto;
}
</style>



对应的值为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// width
clientWidth = 323 = content width(283.2) + 左右 padding(20 * 2) =
width(300) + 左右 padding(20 * 2) - 竖向滚动条宽度 17(若有)

scrollWidth = 323 = clientWidth

offsetWidth = 390 = width(300) + 左右 padding(20 * 2) + 左右 border(25 * 2)

// hieght
clientHeight = 240 = content height(200) + 左右 padding(20 * 2) =
height(200) + 左右 padding(20 * 2) - 横向滚动条高度 17(若有,本次无,为 0)

scrollHeight = 435

offsetHeight = 290 = height(200) + 左右 padding(20 * 2) + 左右 border(25 * 2)

// left、top
offsetTop = 看实际情况
offsetLeft = 看实际情况
clientTop = 25 = border-top
clientLeft = 25 = border-left

快速获取这些值:

1
2
3
4
5
6
7
8
9
10
11
document.某个元素.getBoundingClientRect()
{
bottom: 456, // 等价于 top + offsetHeight
height: 290, // 等价于 offsetHeight
left: 0, // 元素左边与可视窗口的左边距离,有滚动时则实时变化
right: 390, // 等价于 left + offsetWidth
top: 166, // 元素上边与可视窗口的上边距离,有滚动时则实时变化
width: 390, // 等价于 offsetWidth
x: 0, // 等价于 left
y: 166 // 等价于 top
}

实际场景
1、判断元素是否在可视区域内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 方案 1:手动计算
// 先获取可视区域
const { clientWidth, clientHeight } = document.documentElement

// 再获取元素信息
const { top, left, right, bottom } = document.某个元素.getBoundingClientRect()

// 计算逻辑 1:完全在其中,则需满足四个
// 1. 元素.left >= 0
// 2. 元素.top >= 0
// 3. 元素.right <= 窗口宽度(clientWidth)
// 4. 元素.bottom <= 窗口高度(clientHeight)

// 计算逻辑 2:产生交集,则需满足
// 1. 元素.left >= 0
// 2. 元素.top >= 0
// 3. 元素.left <= 窗口宽度(clientWidth)
// 4. 元素.top <= 窗口高度(clientHeight)

// 方案 2:调用 IntersectionObserver API

10、JS 获取各种距离的方法有哪些?
https://mrhzq.github.io/职业上一二事/前端面试/每日一题/10、JS 获取各种距离的方法有哪些?/
作者
黄智强
发布于
2024年1月23日
许可协议