首页 前端知识 JS | 元素视图方法之getBoundingClientRect()方法详解,秒懂!

JS | 元素视图方法之getBoundingClientRect()方法详解,秒懂!

2024-11-04 10:11:54 前端知识 前端哥 371 823 我要收藏

目录

一、getBoundingClientRect()简介

二、getBoundingClientRect()的兼容性

三、getBoundingClientRect()的示例及分析

四、getBoundingClientRect()的应用场景


在前端开发过程中,我们经常需要获取HTML元素的尺寸和位置信息。getBoundingClientRect()方法就是一个非常重要的工具,它可以帮助我们获取元素的大小及其相对于视口的位置。 

一、getBoundingClientRect()简介

1、getBoundingClientRect()方法的含义

getBoundingClientRect()是一个原生的DOM元素的方法,该方法返回一个Object对象,包含元素的大小及其相对于视口的位置。

注意:getBoundingClientRect(),这个方法没有参数的

getBoundingClientRect()用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。也就是说,该方法用于获取DOM元素到浏览器可视范围的距离(不包含文档卷起的部分)。

2、getBoundingClientRect()方法的语法

Element.getBoundingClientRect();

3、getBoundingClientRect()方法的返回值

该函数返回的DOMRect对象,包含6个属性:top,bottom,left,right,width,height。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #box {
        width: 300px;
        height: 300px;
        background-color: aqua;
      }
    </style>
  </head>

  <body>
    <div id="box"></div>
    <script>
      const box = document.getElementById("box");
      const rect = box.getBoundingClientRect();

      console.log(rect.x); // 元素左边界相对于视口的 x 坐标
      console.log(rect.y); // 元素上边界相对于视口的 y 坐标
      console.log(rect.width); // 元素的宽度
      console.log(rect.height); // 元素的高度
      console.log(rect.top); // 元素上边界相对于视口顶部的距离
      console.log(rect.right); // 元素右边界相对于视口左侧的距离 = x + width
      console.log(rect.bottom); // 元素下边界相对于视口顶部的距离 = y + hight
      console.log(rect.left); // 元素左边界相对于视口左侧的距离
    </script>
  </body>
</html>

二、getBoundingClientRect()的兼容性

​getBoundingClientRect() ​方法在大多数现代浏览器中都得到了支持,包括IE5以上的版本。‌ 这个方法最初是由IE引入的,后来被W3C接纳为标准,因此在现代浏览器中的兼容性几乎完美‌。

尽管大多数浏览器都支持getBoundingClientRect方法,但在一些老版本浏览器中仍然存在兼容性问题。例如,IE6和IE7的left和top值会少2px,这是因为HTMl文档根元素默认有2px的边框。此外,Firefox 6以前的版本无法获取top和bottom属性值‌。

为了解决这些兼容性问题,可以通过一些技巧来统一处理。例如,在测试getBoundingClientRect方法时,可以创建一个临时元素来获取其getBoundingClientRect值,然后用这个值来调整原始元素的坐标。这种方法可以确保在不同浏览器中获取到的位置数据一致‌。

1、width和height:ie9及以上支持width / height属性。

ie9以下浏览器只支持 getBoundingClientRect 方法的4个属性:top 、bottom、right、left属性;

ie9 和其它浏览器支持 getBoundingClientRect 方法的6个属性:top 、bottom、right、left、width和height

兼容ie6~ie8的width / height的写法:

var rectWidth = rect.right - rect.left;

var rectHeight = rect.bottom - rect.top;

2、在ie7及ie7以下document.documentElement即html标签的lefttop会多出两个像素。

在ie7及ie7以下的html元素坐标会从(2, 2)开始算起,在ie8已经修复了这个bug。这就是多出两个像素的原因。下面我们做下兼容:

var rectLeft = rect.left - document.documentElement.clientLeft || 2;
var rectRight = rect.right - document.documentElement.clientLeft || 2;
var rectBottom = rect.bottom - document.documentElement.clientTop || 2;
var rectTop = rect.top - document.documentElement.clientTop || 2;

小结:getBoundingClientRect()方法最初是在IE5中引入的,并且现在已经成为W3C标准的一部分,因此在大多数现代浏览器中都得到了良好的支持。‌ 然而,在不同的浏览器和版本中,仍然存在一些兼容性问题需要注意。

在IE浏览器中,尤其是IE6和IE7,getBoundingClientRect()方法返回的lefttop值会比实际位置少2像素,这是因为HTML文档根元素默认有2像素的边框。为了解决这个问题,可以在获取边界之前,创建一个临时元素并设置其样式,然后获取该元素的getBoundingClientRect()值,用这个值来校正原始元素的lefttop值‌。

在FireFox浏览器中,Firefox 6及以前的版本使用getBoundingClientRect()时不能获取到topbottom这两个属性值。从Firefox 6及以后的版本开始,所有四个属性值都能正确获取‌。

对Chrome、Safari等现代浏览器,getBoundingClientRect()方法已经非常成熟,能够正确返回元素的lefttoprightbottomwidthheight属性值‌。

为了确保跨浏览器的兼容性,可以通过以下代码进行兼容处理:

function getElementPosition(element) {
    var rect = element.getBoundingClientRect();
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
    var offset = 2; // 根据需要调整,例如IE6和IE7需要减去2像素
    return {
        left: rect.left + scrollLeft - offset,
        top: rect.top + scrollTop - offset,
        right: rect.right + scrollLeft - offset,
        bottom: rect.bottom + scrollTop - offset,
        width: rect.right - rect.left,
        height: rect.bottom - rect.top
    };
}

三、getBoundingClientRect()的示例及分析

下面是一个小案例,由下图可知当前元素为#box,及box的相关样式(图中红色框),针对返回值进行详细分析与计算。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      #box {
        width: 300px;
        height: 300px;
        border: 16px solid #ccc;
        padding: 10px;
        margin: 90px 120px;
        overflow: auto;
        background-color: aqua;
      }
    </style>
  </head>

  <body>
    <div id="box"></div>
    <script>
      const box = document.getElementById("box");
      const rect = box.getBoundingClientRect();

      console.log(rect.x); // 元素左边界相对于视口的 x 坐标
      console.log(rect.y); // 元素上边界相对于视口的 y 坐标
      console.log(rect.width); // 元素的宽度
      console.log(rect.height); // 元素的高度
      console.log(rect.top); // 元素上边界相对于视口顶部的距离
      console.log(rect.right); // 元素右边界相对于视口左侧的距离
      // 等于y + height)
      console.log(rect.bottom); // 元素下边界相对于视口顶部的距离
      console.log(rect.left); // 元素左边界相对于视口左侧的距离

    </script>
  </body>
</html>

width / height:width和height属性包含了padding和border ,而不仅仅是内容部分的宽度和高度。

● box-sizing:  content-box  ——Standards 模式 | 标准模式 

在标准盒子模型(默认模型)中,这两个属性值分别与元素的 内容区域的宽高width/height + padding + border-width 相等。

● box-sizing:  border-box ——Quirks模式 | 怪异模式

如果是box-sizing:border-box ,两个属性则直接与元素的 width 或 height 相等。


top:图中红色线表示top的取值区域,最外层边框即上边框到窗口顶部的距离。

● 计算:当前元素的margin-top为90,说明元素上边框距离窗口顶部为90px,所以top=90


left:图中蓝色线表示left的取值范围,可知是由最左侧边框及左边框到窗口左侧的距离。

计算:当前元素的margin-left为120,说明元素左边框距离窗口左侧为120px,所left=120


bottom:图中紫色线表示bottom的取值范围,可知是元素的下边框到窗口顶部的距离。

包含元素的元素总高度(border + padding + 元素内容区域的高度content height) + margin。

计算:此时的bottom = border + padding + 元素内容区域的高度 + margin-top,所bottom = (16*2) + (10*2) + 300] + 90 = 442,即等于 y + height


right:图中绿色线表示right的取值范围,可知是元素右边框到窗口顶部的距离。

包含元素的元素总宽度(border + padding + 元素内容区域的宽度content width) + margin。

计算:此时的right = border + padding + 元素内容区域的宽度 + margin-left,所right = (16*2) + (10*2) + 300] + 120 = 472,即等于 y + width


x:元素左上角相对于视口的横坐标,即与left相同,所以x=120。

y:元素左上角相对于视口的纵坐标,即与top相同,所以y=90。

四、getBoundingClientRect()的应用场景

这个方法通常用于需要获取元素在视口中的位置和尺寸信息的场景,比如实现拖拽、定位或响应式布局等,兼容性很好,一般用滚动事件比较多。

特殊场景会用上,比如你登录了淘宝的网页,当你下拉滑块的时候,下面的图片不会立即加载出来,有一个懒加载的效果。当上面一张图片没在可视区内时,就开始加载下面的图片。

参考:图片懒加载四种实现方案之getBoundingClientRect()方法 - 烤地瓜CSDN博客

参考:JavaScript中getBoundingClientRect的使用方法详解及应用场景 - 脚本之家

下面代码就是判断一个容器是否出现在可视窗口内:

 const box = document.getElementById('box')
 window.onscroll = function () {//window.addEventListener('scroll',()=>{})
  console.log(checkInView(box));
 }

function checkInView(dom) {
const { top, left, bottom, right } = dom.getBoundingClientRect();
 return top > 0 &&
        left > 0 &&
        bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
       right <= (window.innerWidth || 
       document.documentElement.clientWidth)
}

getBoundingClientRect()方法的缺点:这个属性频繁计算会引发页面的重绘,可能会对页面的性能造成影响。


● 参考资料 ●

深入理解元素视图的3个方法之getBoundingClientRect()方法 - 博客园

深入理解getBoundingClientRect:前端开发的定位利器-百度开发者中心

Js中的getBoundingClientRect | 从getBoundingClientRect()设置边距

js getBoundingClientRect使用方法详解_javascript技巧_脚本之家

超详细分析!!!秒懂getBoundingClientRect()-CSDN博客

—— 图片懒加载四种实现方案之getBoundingClientRect()方法 - 烤地瓜CSDN博客 ——

转载请注明出处或者链接地址:https://www.qianduange.cn//article/19923.html
评论
发布的文章

JQuery中的load()、$

2024-05-10 08:05:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!