目录
一、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标签的left和top会多出两个像素。
在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()
方法返回的left
和top
值会比实际位置少2像素,这是因为HTML文档根元素默认有2像素的边框。为了解决这个问题,可以在获取边界之前,创建一个临时元素并设置其样式,然后获取该元素的getBoundingClientRect()
值,用这个值来校正原始元素的left
和top
值。
在FireFox浏览器中,Firefox 6及以前的版本使用getBoundingClientRect()
时不能获取到top
和bottom
这两个属性值。从Firefox 6及以后的版本开始,所有四个属性值都能正确获取。
对Chrome、Safari等现代浏览器,getBoundingClientRect()
方法已经非常成熟,能够正确返回元素的left
、top
、right
、bottom
、width
和height
属性值。
为了确保跨浏览器的兼容性,可以通过以下代码进行兼容处理:
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博客 ——