如何获取dom元素的位置、尺寸?client、scroll、offset?一文搞懂!!

1,855 阅读5分钟

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

现实中,用户的屏幕尺寸大不相同,我们经常需要实时获取某些dom元素的位置信息,或者屏幕、页面窗口的信息,今天就来归纳性的讲讲

本文推荐结合代码实例阅读:代码仓库直通车

为了方便理解我按照顺序,从大到小获取,依次是:屏幕尺寸、窗口尺寸、文档区尺寸、dom位置。

获取屏幕尺寸

需要通过window.screen对象中获取当前屏幕的详情,这个方法获取到的属性值是以像素计算的,这个不能作为获取到当前屏幕是几k屏的依据(因为有缩放的关系,有的2k屏放大200%后的宽高就没那么大了)

  // 一般获取到这四个就可以了,其它的不做关注
  // height: 屏幕高度,像素计;
  // width: .
  
  let {height, width} = screen;

image-20210807224939987.png

获取窗口、文档区尺寸

关于浏览器的窗口有两种,一种是浏览器实际占据的像素尺寸(红色框),另一种是我们开发的页面占据的尺寸(文档区蓝色框)。实际我们开发中我们使用的地方只是在浏览器提供的窗口里(第二种情况)

image-20210807232142984.png

获取方式

  • 方式一,通过window对象获取,这里的值可以被修改

    // 这四个值得对应关系如上图
    // outerHeight:浏览器当前可使用的高度,这里是860,其实就是减掉了任务管理器的高度,当你隐藏任务栏时,outerHeight就和height相等了;
    // innerHeight、innerWidth;文档显示区的宽高,不包含滚动条的长度(这个意思是没有显示的内容不算进来),自己去体会一下;
    let {innerHeight, innerWidth, outerHeight, outerWidth} = window
    
  • 方式二,通过screen对象获取,这里的不可以被修改

    这里只能获取到浏览器的可视宽高,文档区宽高获取不到

    // availHeight, availWidth  等价于  outerHeight, outerWidth
    let {availHeight, availWidth} = screen;
    

dom位置

最常见的就是这种情况了,任意一个dom我怎么知道它的宽高,位置信息呢?,如下图所示有一个父元素,包含两个子元素。

getComputedStyle

拿到这个案例,首先假设有这么一个需求,获取父元素的位置、宽高,可以借助一个window上的方法获取到该元素的所有css信息getComputedStyle

  • getComputedStyle浅试

    image-20210808092122365.png

    const father = document.querySelector(".father");
    const style = window.getComputedStyle(father);
    console.log("father.getComputedStyle", style);
    

    获取到的属性值简直不要太多,如下图所示,密密麻麻,可以从中获取到自己想要的任何信息

    image-20210808100145485.png

直接使用dom获取

```js
const father = document.querySelector(".father");
console.log("father", [father]);	// 小技巧:把元素放到数组内,展开可以看到全部属性数据~~ 超实用!!!
```

image-20210808103026628.png

getBoundingClientRect 获取

father.getBoundingClientRect()

image-20210808115349042.png

// 对于位置信息上图已经很准确的表达清楚(x, y, top, left, bottom, right);
// 唯一需要注意的是bottomright和我们定位用的概念不一样,注意看图上;

// 对于 widthheight 相当于 offsetWidth 、 offsetHeight,关于这两个的详解请继续往下看。

详解位置信息中三大家族的含义

前面我们已经能拿到所有的样式信息了,但这其中关于元素位置信息的属性(概念)有点多,让人脑壳有点疼,其中有client家族、scroll家族、offset家族,这些属性都是很有用的信息,下面分别介绍

client家族

  • clientHeight 、clientWidth 结果只包含content+padding,联想记忆:标准盒模型
  • clientLeft、 clientTop 结果是border-left、border-top的值

image-20210808104126101.png

{
    clientHeight: 310,
    clientLeft: 10,
    clientTop: 0,
    clientWidth: 483
}

scroll家族

代表的是与滚动条相关的尺寸

  • scrollHeight、scrollWidth结果只包含content,但是如果出现滚动条,会包含滚动条未出现部分的尺寸

  • scrollLeft、 scrollTop结果代表滚动条滚动的距离

    • 表示滚动条到底的公式

      const onScrollBottom = father.scrollTop + father.clientHeight  === father.scrollHeight
      

image-20210808105214396.png

{
    scrollHeight: 600,
    scrollLeft: 0,
    scrollTop: 108,
    scrollWidth: 483
}

offset家族

代表的是外围的尺寸,就是最外圈的尺寸

  • offsetHeight、offsetWidth的结果就是border + padding + content,即:元素的可见部分

  • offsetLeft、 offsetTop的结果返回当前元素左上角相对于 HTMLElement.offsetParent父节点的左边界偏移的像素值,左上角位于父元素中的坐标,可以衍生出其余三点位于父元素中的坐标

    // 右上角
    const topRightCorner = {
        top: ele.offsetTop,
        right: ele.offsetLeft + ele.offsetWidth
    }
    // 左下角
    const bottomLeftCorner = {
        bottom: ele.offsetTop + ele.offsetHeight,
        left: ele.offsetLeft
    }
    // 右下角
    const bottomRightCorner = {
        bottom: ele.offsetTop + ele.offsetHeight,
        right: ele.offsetLeft + ele.offsetWidth
    }
    

image-20210808112436745.png

{
    offsetHeight: 330,
    offsetLeft: 100,
    offsetTop: 200,
    offsetWidth: 520
}

小结

对于上面的三大类位置信息,适用于每个dom元素,所以不对子元素进行分析,可以总结为以下几点:

  • 拿元素位于父元素中的位置、以及尺寸? 答:用offset家族;
  • 拿元素内容可见内容尺寸?答:用client家族;
  • 拿元素总的内容长度(包含滚动条以下没显示出来的)?答:用scroll家族

首先要分类好自己的需求,然后才能根据需求获取对应的位置信息。

本章练习题

1、当我切换box-sizing时(border-box,content-box),上述判断见底公式是否成立? 😄欢迎回复

本章小结

内容有些多,而且我写的可能也不是很容易理解,望珍重~~😂😂😂😂😂😂😂😂😂😂😂😂😂😂😂😂