页面
| 对象 | 距离 |
|---|---|
| pageXOffset/scrollX | 返回文档/页面水平方向滚动的像素值。 |
| pageYOffset/scrollY | 返回文档在垂直方向已滚动的像素值。 |
| innerHeight | 用于获取浏览器窗口的视口(viewport)高度,即可见区域的高度,以像素为单位。 |
pageYOffset:该属性提供了文档从顶部位置垂直滚动的像素数。大多数现代浏览器都支持该属性,包括Firefox、Chrome、Safari和Edge。scrollY:该属性是pageYOffset的别名,提供相同的功能。大多数现代浏览器都支持该属性,包括Firefox、Chrome、Safari和Edge。然而,需要注意的是Internet Explorer不支持scrollY。
需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:
- 声明了 DTD,使用 document.documentElement.scrollTop
- 未声明 DTD,使用 document.body.scrollTop
- 新方法 window.pageYOffset和 window.pageXOffset,IE9 开始支持
function getScroll() {
return {
left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
};
}
使用的时候 getScroll().left
// 获取浏览器窗口的视口高度
var viewportHeight = window.innerHeight;
// 输出视口高度
console.log('视口高度:' + viewportHeight + 'px');
鼠标事件中距离
| 对象 | 说明 |
|---|---|
| clientX / clientY | 鼠标相对于浏览器窗口可视区的x和y坐标 |
| pageX / pageY | 鼠标相对页面文档的x和y坐标(跟随滚动) IE9+支持 |
| screenX / screenY | 鼠标相对于电脑屏幕的x和y坐标 |
| offsetX / offsetY | 鼠标元素的内部坐标的x和y坐标 |
说明:
offsetY 计算
OffsetY 并不是event 原生的属性,e.pageY 减去 getBoundingClientRect().top 减去 window.pageYOffset 算出来的。
OffsetY= e.pageY - getBoundingClientRect().top - window.pageYOffset
getBoundingClientRect 是什么:
getBoundingClientRect 是返回元素距离可以可视区域的距离和宽高的。
<script>
// 鼠标事件对象 MouseEvent
document.addEventListener('click', function(e) {
// 1. client 鼠标在可视区的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
console.log('---------------------');
// 2. page 鼠标在页面文档的x和y坐标(跟随滚动)
console.log(e.pageX);
console.log(e.pageY);
console.log('---------------------');
// 3. screen 鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);
})
</script>
元素距离
偏移 offset系列
offset 翻译过来就是偏移量, 我们使用 offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。
-
获得元素距离带有定位父元素的位置
-
获得元素自身的大小(宽度高度)
-
注意:返回的数值都不带单位
| element.offsetParent | 返回作为该元素带定位的父级元素,如果父级都没有定位,返回body | |
|---|---|---|
| element.offsetTop | 返回元素相对带定位父元素的上方的偏移 (是距离最近的有 position 属性(relative 或 absolute 或 fixed)的元素的距离。) | |
| element.offsetLeft | 返回元素相对带定位父元素的左边框的偏移 | |
| element.offsetWidth | 返回元素在水平方向上的总宽度,包括元素的内容宽度、内边距(padding)、滚动条(如果存在)的宽度以及边框(border)的宽度。 | 包含padding+border+width只读属性,只能获取不能赋值 |
| element.offsetHeight | 返回元素在垂直方向上的总高度,包括元素的内容高度、内边距(padding)、滚动条(如果存在)的高度以及边框(border)的高度 |
<body>
<div class="father">
<div class="son"></div>
</div>
<div class="w"></div>
<script>
// offset 系列
var father = document.querySelector('.father');
var son = document.querySelector('.son');
// 1.可以得到元素的偏移 位置 返回的不带单位的数值
console.log(father.offsetTop);
console.log(father.offsetLeft);
// 它以带有定位的父亲为准 如果么有父亲或者父亲没有定位 则以 body 为准
console.log(son.offsetLeft);
var w = document.querySelector('.w');
// 2.可以得到元素的大小 宽度和高度 是包含padding + border + width
console.log(w.offsetWidth);
console.log(w.offsetHeight);
// 3. 返回带有定位的父亲 否则返回的是body
console.log(son.offsetParent); // 返回带有定位的父亲 否则返回的是body
console.log(son.parentNode); // 返回父亲 是最近一级的父亲 亲爸爸 不管父亲有没有定位
</script>
</body>
可视区client 系列
client 翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client
系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
| element.clientTop | 返回元素上边框的大小 |
| element.clientLeft | 返回元素左边框的大小 |
| element.clientWidth | 返回自身包括padding 、内容区域的宽度,不含边框,返回数值不带单位 |
| element.clientHeight | 返回自身包括padding 、内容区域的高度,不含边框,返回数值不带单位 |
<body>
<div></div>
<script>
// client 宽度 和我们offsetWidth 最大的区别就是 不包含边框
var div = document.querySelector('div');
console.log(div.clientWidth);
</script>
</body>
元素滚动 scroll 系列
scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。
| element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位 |
| element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位 |
| element.scrollWidth | 返回自身实际的宽度,不含边框 返回自身实际的宽度,不含边框 |
| element.scrollHeight | 返回自身实际的高度,不含边框返回自身实际的高度,不含边框 |
主要用法:
1.offset系列 经常用于获得元素位置 offsetLeft offsetTop
2.client经常用于获取元素大小 clientWidth clientHeight
3.scroll 经常用于获取滚动距离 scrollTop scrollLeft
4.注意页面滚动的距离通过 window.pageXOffset 获得
clientHeight 是内容区域的高度,不包括 border。
offsetHeight 包括 border。
scrollHeight 是滚动区域的总高度,不包括 border。
那看起来 getBoundingClientRect().height 和 offsetHeight 一模一样?
getBoundingClientRect 拿到的包围盒的高度,而 offsetHeight 是元素本来的高度。
案例
获取元素的偏移量
function getTotalOffsetTop(element: HTMLElement) {
let totalOffsetTop = 0;
while (element) {
if(totalOffsetTop > 0) {
totalOffsetTop += element.clientTop;
}
totalOffsetTop += element.offsetTop;
element = element.offsetParent as HTMLElement;
}
return totalOffsetTop;
}
总结
这类属性比较多,我们整体过了一遍:
- e.pageY:鼠标距离文档顶部的距离
- e.clientY:鼠标距离可视区域顶部的距离
- e.offsetY:鼠标距离触发事件元素顶部的距离
- e.screenY:鼠标距离屏幕顶部的距离
- winwodw.scrollY:页面滚动的距离,也叫 window.pageYOffset,等同于 document.documentElement.scrollTop
- element.scrollTop:元素滚动的距离
- element.clientTop:上边框高度
- element.offsetTop:相对有 position 的父元素的内容顶部的距离,可以递归累加,加上 clientTop,算出到文档顶部的距离
- clientHeight:内容高度,不包括边框
- offsetHeight:包含边框的高度
- scrollHeight:滚动区域的高度,不包括边框
- window.innerHeight:窗口的高度
- element.getBoundingClientRect:拿到 width、height、top、left 属性,其中 top、left 是元素距离可视区域的距离,width、height 绝大多数情况下等同 offsetHeight、offsetWidth,但旋转之后就不一样了,拿到的是包围盒的宽高
其中,还要注意 react 的合成事件没有 offsetY 属性,可以自己算,react-use 的 useMouse 的 hook 就是自己算的,也可以用 e.nativeEvent.offsetY 来拿到。