clientWidth 和 clientHeight
clientWidth (opens in a new tab) 和 clientHeight (opens in a new tab) 属性返回元素的内容区的宽度和高度,不包括边框、滚动条和内边距。
- 它是个只读属性
- 对于 html 和 body 的 clientHeight,返回的是 viewport 的高度,不算滚动条
- 对于 inline box 的元素,获取的值为 0 (zero for elements with no CSS or inline layout boxes)
offsetWidth 和 offsetHeight
offsetWidth (opens in a new tab) 和 offsetHeight (opens in a new tab) 属性返回元素的内容区的宽度和高度,包括内边距、滚动条和边框
。
- 它是一个只读属性
- 是 CSS 高度的衡量标准,包括元素的边框、内边距和元素的水平滚动条(如果存在且渲染的话),不包含:before 或:after 等伪类元素的高度
- 如果元素被隐藏(元素或者元素的祖先之一的元素的 style.display 被设置为 none),则返回 0
- offsetHeight 会被四舍五入为整数值,如果需要一个浮点数值,请用 element.getBoundingClientRect()
对比 clientHeight 和 offsetHeight
offsetHeight = Visible content height + padding + border + scrollbar
clientHeight = Visible content height + padding
innerWidth 和 innerHeight
innerWidth (opens in a new tab) 和 innerHeight (opens in a new tab) 属性返回窗口的视口的宽度和高度。这些属性是只读的,但是可以通过设置 window.resizeTo() (opens in a new tab) 和 window.resizeBy() (opens in a new tab) 来改变窗口的大小。
获取浏览器视口高度的兼容写法
const height =
window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
outerWidth 和 outerHeight
outerWidth (opens in a new tab) 和 outerHeight (opens in a new tab) 属性返回浏览器的宽度和高度,以像素计,包括工具栏/滚动条的宽度。
scroll 相关 API
1. scrollWidth (opens in a new tab) 和 scrollHeight (opens in a new tab) 属性返回元素的内容区的宽度和高度,包括内边距
和由于溢出导致的视图中不可见内容
,但不包括滚动条、边框和外边距。
- 它是一个只读属性
- 一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容
- 没有垂直滚动条的情况下,scrollHeight 值与元素视图填充所有内容所需要的最小值 clientHeight 相同
- scrollHeight 也包括::before,::after 这样的伪元素
2. scrollLeft (opens in a new tab) 和 scrollTop (opens in a new tab) 属性返回元素的内容区的左上角相对于元素左上角的偏移量,可以修改。
Element.scrollTop
属性可以获取或设置一个元素的内容垂直滚动的像素数。Element.scrollLeft
属性可以读取或设置元素滚动条到元素左边的距离。
需要额外注意的是: 注意如果这个元素的内容排列方向(direction) 是 rtl (right-to-left) ,那么滚动条会位于最右侧(内容开始处),并且 scrollLeft 值为 0。此时,当你从右到左拖动滚动条时,scrollLeft 会从 0 变为负数。
const button = document.getElementById("slide");
button.onclick = () => {
document.getElementById("container").scrollLeft += 20;
};
3. Element.scroll() (opens in a new tab) 方法滚动元素的内容区域,使得指定的元素的左上角出现在视图中的指定坐标处。
// 方法一
element.scroll(x-coord, y-coord)
element.scroll(options)
// 方法二
// 同时也支持 `element.scroll(options)` 方式调用,支持传入额外的配置:
{
left: number,
top: number,
behavior: 'smooth' | 'auto' // 平滑滚动还是默认直接滚动
}
x-coord
是指在元素左上方区域横轴方向上想要显示的像素。y-coord
是指在元素左上方区域纵轴方向上想要显示的像素。
判断当前元素是否存在滚动条,出现滚动条便意味着元素空间将大于其内容显示区域,根据这个现象便可以得到判断是否出现滚动条的规则。
export const hasScrolled = (element, direction) => {
if (!element || element.nodeType !== 1) return;
if (direction === "vertical") {
return element.scrollHeight > element.clientHeight;
} else if (direction === "horizontal") {
return element.scrollWidth > element.clientWidth;
}
};
判断用户是否滚动到底部,本质上就是当元素出现滚动条时,判断当前元素
出现的高度 + 滚动条高度 = 元素本身的高度(包含隐藏部分)
。
element.scrollHeight - element.scrollTop === element.clientHeight;
getBoundingClientRect()
getBoundingClientRect() (opens in a new tab) 方法返回元素的大小及其相对于视口的位置。
element.getBoundingClientRect()返回的 height 和 width 是针对元素可见区域的宽和高(具体尺寸根据 box-sizing 决定),并不包含滚动条被隐藏的内容。
如果是标准盒子模型,元素的尺寸等于 width/height + padding + border-width 的总和。如果 box-sizing: border-box,元素的的尺寸等于 width/height。
计算元素是否出现在视口内 利用的还是元素距离视口的位置小于视口的大小。
注意即便变成了负值,那么也表示元素曾经出现过在屏幕中只是现在不显示了而已。(就比如滑动过)
vue-lazy
图片懒加载库源码就是这么判断的。
isInView (): boolean {
const rect = this.el.getBoundingClientRect()
return rect.top < window.innerHeight && rect.left < window.innerWidth
}
如果
rect.top < window.innerHeight
表示当前元素已经已经出现在(过)页面中,left 同理。
getClientRects()
getClientRects() (opens in a new tab) 方法返回一个包含元素的所有盒子的列表,这些盒子是元素的边框,以及元素的内边距和边框。