Html 页面中的各种距离 小记

79 阅读5分钟

页面

对象距离
pageXOffset/scrollX返回文档/页面水平方向滚动的像素值。
pageYOffset/scrollY返回文档在垂直方向已滚动的像素值。
innerHeight用于获取浏览器窗口的视口(viewport)高度,即可见区域的高度,以像素为单位。
  1. pageYOffset:该属性提供了文档从顶部位置垂直滚动的像素数。大多数现代浏览器都支持该属性,包括Firefox、Chrome、Safari和Edge。
  2. scrollY:该属性是pageYOffset的别名,提供相同的功能。大多数现代浏览器都支持该属性,包括Firefox、Chrome、Safari和Edge。然而,需要注意的是Internet Explorer不支持scrollY

需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:

  1. 声明了 DTD,使用 document.documentElement.scrollTop
  2. 未声明 DTD,使用 document.body.scrollTop
  3. 新方法 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系列相关属性可以动态的得到该元素的位置(偏移)、大小等。

  1. 获得元素距离带有定位父元素的位置

  2. 获得元素自身的大小(宽度高度)

  3. 注意:返回的数值都不带单位

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 来拿到。

参考:mp.weixin.qq.com/s/I0v6yi0rh…