当前位置: 首页 > Web前端 > HTML5

浏览器元素大小和位置查询指南

时间:2023-04-05 14:38:00 HTML5

前言本文主要介绍几种在浏览器中获取坐标和大小的方法。是一篇比较全面的文章。在浏览器中获取元素的坐标和大小非常容易。有很多方法可以实现这些需求,但是凌乱的API和大量的兼容处理导致在浏览器中没有直接的方法可以得到我们想要的结果。仔细想想这个问题,为什么浏览器不直接提供一个简单的属性来告诉你浏览器窗口的大小,或者某个元素的宽高。以div元素为例,我们有很多问题影响元素的宽高:border是否包含在宽高的计算中?padding是否包含在宽高的计算中?magin是否包含在width中如何计算height?框大小:边框框;如何计算呢?父元素使用overflow:hidden;切割我们的元素,此时宽高如何计算呢?该元素使用溢出并出现滚动条。如何计算?而如果要获取一个浏览器窗口的大小,就得面对我们要获取哪个大小?屏幕尺寸?浏览窗口大小?浏览区域大小?它包括滚动条吗?面对兼容性问题,我要向我们心爱的IE浏览器致敬,但本文不讨论浏览器之间的差异。不过本文涉及的内容在IE9及以上版本应该可以正常使用(但建议大家查看caniuse或者MDN)。浏览器浏览器部分的宽高计算主要是通过window对象完成的。这个对象提供了几个关键属性:window.innerWidthwindow.innerHeightwindow.outerWidthwindow.outerHeight用人类的语言来描述这些属性是。属性名人类的解释innerWidth获取页面可见区域的宽度,包括右边的滚动条(如果任何)。所谓可见区域就是HTML页面的内容区域,不包括浏览器自身的ui(地址栏和菜单栏等)所占用的空间。innerHeight获取页面可见区域的高度,包括底部的滚动条(如果有的话)。解释同上。outerWidth获取浏览器窗口的宽度。outerHeight获取浏览器窗口的高度。windows绘图中的友星:注:单位为px。注意:滚动条不被视为浏览器ui中的内容,而是被视为内容区域的一部分。右侧默认滚动条的宽度包含在window.innerWidth中,但不属于html元素和html下的任何元素。元素部分属性属性名称人工解释element.cclientWidth元素内容区域的宽度+padding的宽度。如果宽度溢出并被裁剪,则裁剪的部分不包括在内。element.scrollWidth元素的实际大小包含父元素出现滚动条后未显示的部分。计算范围为padding+content,clientWidth与element.offsetWidth一致,相当于clientWidth计算边框宽度。宽度计算为content+padding+border.element.clientHeight元素内容区域高度+padding高度。如果高度溢出并被裁剪,裁剪的part.element将不被包含在内。scrollHeight当子元素的高度溢出时,这里是子元素包含溢出部分的高度,大小计算同clientHeight。element.offsetHeight相当于clientHeight用于计算边框的高度,计算高度为content+padding+border.element.clientLeftelement.leftborder.scrollLeft的宽度计算比较复杂。见后续详细解释。element.offsetLeft的计算比较复杂。请参阅以下详细说明。下面详细解释滚动条的规则。不管是水平滚动条还是垂直滚动条,clientXXX的计量单位都不包括滚动条的宽度(高度)。例如下图中,我们测量父元素(黑色区域)的clientWidth结果与子元素(红色区域)的clientWidth大小相同。但是需要注意的是,一旦出现滚动条,clientWidth的宽度就会变小(高度不变)。注意:图中所示的宽度clientWidthAPI名称是否包含滚动条的大小?offsetXXX包含clientXXX不包含scrollXXX不包含so在margin:0;padding:0;border-width:0;offsetWidth-clientWidth=滚动条的宽度。通过这种方式我查出了chrome浏览器滚动条的大小是17px,但是不要忘记这些API只返回整数。注意:scrollXXX滚动条计算和clie的规则ntXXX的性能是一样的。对于box-sizing:border-box的计算,请记住对于clientXXX,元素的大小是padding+content。使用border-box后,元素的表现是padding和border的修改不会影响To元素的大小。这时候宽度和clientWidth一样多,高度也一样。但是别忘了border不参与clientXXX的计算,所以border的修改不会影响元素的宽高。那么当边框变大时,对应的clientXXX变小。一个元素被设置为border-box:box{width:100px;填充:20px;边框:20px实心;box-sizing:border-box;}此时clientWidth=100px-20px*2(大约为边框的宽度)=60px由于offsetXXX的计算包括了边框的尺寸,如果一个元素设置了边框-box,那么offsetWidth就等于元素的宽度,因为border是有宽度限制的。offsetTop和offsetLeft子元素的offsetWidth|height是相对于父元素内容区域(padding+content)左侧和顶部的偏移量。这两个是相对值,是parent使用orientation时计算的。这个父元素可以通过HTMLElement.offsetParent来获取。例如:父级使用绝对或相对。注意:后面提到的父元素是指使用相对定位的父元素。注意:以上都是针对块级元素描述的,对于内联元素或者td元素,相对父元素是不同的。这里不考虑这些情况。有关详细信息,请参阅上面的链接。情况1当子元素使用绝对定位时,父元素不能干扰子元素,所以子元素的scrollLeft为left+margin-left。情况2第二种情况是父元素和子元素都使用了相对定位,并且相对定位没有脱离文档流,那么父元素的padding-left会影响子元素的scrollLeft属性。在线例子注:offsetTop和Left好像在不同浏览器下计算值不一样,会造成兼容性问题,这里就不展开了。有兴趣的读者可以参考相关资料。scrollTop和scrollLeft首先scrollTop和scrollLeft是一对可读可写的属性,也就是说你可以获取他的值或者设置它来控制滚动的距离。注意:scrollTop|scrollLeft用在包含滚动区域的元素上(图中黑色边框的元素),而不是在滚动元素上测量,滚动元素的scrollTop始终为0。简单理解:topof包含滚动条的元素在垂直方向的内容区域(padding+content)是相对于其上边框底部向上移动的距离(水平方向也是如此)。就是scrollTop的大小(图中超出的部分)。元素方法getBoundingClientRect建议阅读此方法的MDN指南。当然,你也可以选择听我说。.这个api最早是由ie提出的(早在ie4)。也是ie对web开发的贡献之一。调用此api将返回一个DOMRect对象。该对象多次更改名称,但基本概念没有改变。.当你调用这个方法时,它会返回一个对象,它有以下属性:lefttoprightbottomwidthheightxy注意:截至2019年4月5日,ie9+包括边缘兼容的宽度和高度。ie和edge与x和y不兼容。而属性返回的值有两点不同:返回值是相对值,相对于浏览器视口左上角返回的值包含小数部分,这意味着获取的值更准确如何理解:如果页面中只有一个1000px高100%宽的div(没有margin,padding,border),那么它的bottom和height应该是1000,left和top是0,right和width是元素宽度:因为我们指定1000px所以它的高度是1000,因为页面上只有一个元素,它的内容区域底部到可见区域顶部的距离是1000,所以底部是1000。因为页面上只有一个元素页面,这个元素附加在可见区域的top和left上是的,所以left和top的两个值都是0。div默认会覆盖水平空间,里面只有我们的div水平空间,所以视口区域右边到左边的距离就是元素的宽度,也就是当前可见区域注意:left,right,top,bottom指的是到内容区域边缘的距离到视口的左上角,不包括边框和边距,填充,如果指定了box-sizeing:边框框;还包括边框和填充。但是,由于对象的值是相对值,视口会移动,视口移动后top和left的值也会发生变化。说明:注意:此属性返回的值也将滚动条视为宽度(垂直)和高度(水平)的一部分。类似于getBoundingClientRect,还有一个api叫getClientRects。这个api稍微复杂一点,只是简单的作用在内部链接元素的时候,两者是有区别的。首先,它返回一个包含内联元素所有行的DOMRect对象数组。当行内元素只有一行时,这两个API的表现是一样的。想想之前关于getClientRects的讨论https://segmentfault.com/q/10...screen部分主要用到了window.screen对象,它抽象代表了当前正在使用的物理显示设备。是的,这个属性是跟硬件相关的,一般web开发中很少用到这个属性。通过这个对象,可以得到屏幕的分辨率等信息。这里就不介绍了。附详细文章:https://www.cnblogs.com/ndos/...另外,windows上还有几个screen属性:名称说明screenLeft浏览器窗口左侧到窗口左边缘的距离screenscreenTop浏览器窗口顶部到屏幕上边缘的距离screenX与screenLeftscreenY计算相同screenTopStyleHTMLelement.style是常用的操作,使用styles获取size和定位elements,但是问题出在使用HTMLelement.style获取的内容:带有css单位的字符串需要写成inline才能使用获取元素的大小或者宽高无疑是方便的。这里返回的值与css模型是一致的。window.getComputedStyleAPI和HTMLelement.style类型,调用该API返回CSSStyleDeclaration对象。区别在于:read-only可以使用css全名来获取样式,例如font-size不仅计算内联样式还包括样式表中的样式注意:修改元素的样式时,对应的CSSStyleDeclaration也会实时同步,不需要不断获取一个元素。滚动相关属性使用对象API名称描述windowpageXoffset视口相对于页面内容区域左侧的距离。在现代浏览器上,此值可能返回双精度浮点windowpageYoffset。从视口顶部到页面内容区域顶部的距离。在现代浏览器上,这个值可能返回一个双精度浮点类型windowscrollX与pageXoffsetwindowscrollY与pageYoffset相同MDN滚动参数兼容性参考https://developer.mozilla.org...方法简述:适用对象API名称描述windowscrollBy滚动到相对于当前滚动位置的指定位置windowscrollByLinesrelative根据当前滚动位置的行数滚动(非标准)windowscrollByPages根据当前滚动位置相对的页数滚动(非-standard)windowscroll绝对滚动到某个位置windowscrollTo与scroll方法功能相同windowscrollMaxX获取水平滚动距离的限制(非标准)windowscrollMaxY获取垂直方向滚动距离的限制(非标准)elementscrollTo用在元素上的scrollTo方法上,作用和window上一样。elementscrollBy用在element上的scrollBy方法上,作用在window上方法和elementscroll用在element上的scroll方法一样,作用和window上的方法一样。