当前位置:首页 » 《休闲阅读》 » 正文

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

5 人参与  2024年11月19日 09:21  分类 : 《休闲阅读》  评论

点击全文阅读


目录

一、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博客 ——


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/188571.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1