1 元素的大小、滚动
元素具有以下几何属性:
offset系列:
offsetParent
— 是最接近的 CSS 定位的祖先(relative、absolute、fixed),或者是 td,th,table,body。offsetLeft/offsetTop
— 是相对于 offsetParent 的左上角边缘的坐标。offsetWidth/offsetHeight
— border+padding+content。
client系列
clientLeft/clientTop
— 从元素padding外侧左上角到border外侧左上角的距离。但是要记住一句话“在有些浏览器中,这个滚动条占据了content的宽度,却放在padding外”。因此对于从右向左阅读的语言,clientLeft会不太一样。clientWidth/clientHeight
— padding+content,不包括滚动条(但滚动条有可能占据content宽度,滚动条一般为16px)。
scroll系列
scrollWidth/scrollHeight
— 全部内容+padding的 width/height,就像 clientWidth/clientHeight 一样,但还包括元素的滚动出的不可见的部分。不包括滚动条。scrollLeft/scrollTop
— 从元素的左上角开始,滚动出元素的上半部分的 width/height。
除了 scrollLeft/scrollTop 外,所有属性都是只读的。如果我们修改 scrollLeft/scrollTop,浏览器会滚动对应的元素。
2 window/document的大小、滚动
几何:
- window(视窗)部分的
width / height
(内容区域的 width / height):document.documentElement.clientWidth / clientHeight
- 整个文档的
width / height
,其中包括滚动出去的部分:let scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight );
滚动:
- 读取当前的滚动:
window.pageYOffset / pageXOffset
。 - 更改当前的滚动:
window.scrollTo(pageX, pageY)
— 绝对坐标,window.scrollBy(x, y)
— 相对当前位置进行滚动,elem.scrollIntoView(top)
— 滚动以使 elem 可见(elem 与窗口的顶部 / 底部对齐)。
3 坐标
元素的窗口坐标示意图:
3.1 页面上的任何点都有坐标:
- 相对于窗口的坐标 —
elem.getBoundingClientRect()
。 - 相对于文档的坐标 —
elem.getBoundingClientRect()
加上当前页面滚动。
3.2 文档坐标与窗口坐标的关系:
- pageY = clientY + 文档的垂直滚动出的部分的高度。
- pageX = clientX + 文档的水平滚动出的部分的宽度。
// 获取元素的文档坐标
function getCoords(elem) {
let box = elem.getBoundingClientRect();
return {
top: box.top + window.pageYOffset,
right: box.right + window.pageXOffset,
bottom: box.bottom + window.pageYOffset,
left: box.left + window.pageXOffset
};
}
窗口坐标非常适合和 position:fixed
一起使用,文档坐标非常适合和 position:absolute
一起使用。
这两个坐标系统各有利弊。有时我们需要其中一个或另一个,就像 CSS position 的 absolute 和 fixed 一样。