likes
comments
collection
share

js中获取dom尺寸【简单易懂】👌

作者站长头像
站长
· 阅读数 52

前言

直接要答案的,看目录中的最佳实践。

根据实际应用场景不同,选择的方法至关重要。

前置知识

前置知识可帮助你快速了解到一个盒子的组成部分。

首先我们要知道一个盒子的组成部分分为4个,

  • 内容区域Content Box
  • 内边距Padding
  • 边框Border<滚动条属于边框部分>
  • 外边距margin

外边距作为盒子外部的区域,定义的是元素与其他元素之间的空白区域,常用做布局中的间距调整,所以大多数情况,我们要获取的盒子大小,不包括外边距。

现在可以了解一下box-sizing属性了。👀

定义:

CSS中的box-sizing属性定义了user agent应该如何计算一个元素的总宽度和总高度

通俗的理解 box-sizing的值,决定了代码中width或height的值指向盒子的那些部分。

属性值:

content-box 默认值,标准盒子模型。width 与 height 只包括内容的宽和高,不包括边框(border),内边距(padding),外边距(margin)。注意:内边距、边框和外边距都在这个盒子的外部。比如说,.box {width: 350px; border: 10px solid black;} 在浏览器中的渲染的实际宽度将是 370px。

尺寸计算公式:

width = 内容的宽度

height = 内容的高度

宽度和高度的计算值都不包含内容的边框(border)和内边距(padding)

我将其通俗理解为 在值为content-box的时候,你所定义的widthheight指的是内容区域Content Box的宽高,并不包括内边距Padding和边框Border

下面看图理解

js中获取dom尺寸【简单易懂】👌

代码中三个盒子都指定了宽高为100px,但是给第二个盒子加了10px内边距,他渲染出来就比100px大,给第三个盒子加了20px的边框,他渲染出来就比100px大。也就是说你所指定的宽高只是内容区域的宽高,并不包括内边距和边框,所以在这种模式下,浏览器最终渲染出的尺寸和你所指定的尺寸并不一定相等。

width 和 height 属性包括内容,内边距和边框,但不包括外边距。这是当文档处于 Quirks 模式 时 Internet Explorer 使用的盒模型。注意,填充和边框将在盒子内 , 例如, .box {width: 350px; border: 10px solid black;} 导致在浏览器中呈现的宽度为 350px 的盒子。内容框不能为负,并且被分配到 0,使得不可能使用 border-box 使元素消失。

也就是说在值为border-box的时候,你所定义的widthheight就已经包括了内边距和边框

继续看图理解

js中获取dom尺寸【简单易懂】👌

这次在指定了box-sizing: border-box后,再给盒子添加内边距或边框,都不会改变你所定义的盒子大小了。

但是!但是有个例外情况 看下图

js中获取dom尺寸【简单易懂】👌

当你的边框或者内边距,超过你指定的宽高时,盒子就会被撑大了,上图可以看到,当边框为51px时,盒子就变大了,因为左边框右边框 加起来102px,已经超过盒子的原本宽度100px,但是这种情况基本不会遇到吧。

所以在值为border-box并且边框和内边距不大于你所指定的尺寸时,浏览器最终渲染出的尺寸和你所指定的尺寸就相等。

非标准,不推荐使用

注意:这个值在大多数浏览器中不支持,不建议在生产环境中使用。

正文开始✌

1. dom.style.width ❌

此方法只能获取行内样式,并且获取的只是行内样式中你所书写的宽度,并不一定是渲染出来的真正宽度。看图

js中获取dom尺寸【简单易懂】👌

第一个盒子没写行内样式,所以dom.style.width获取到是空字符串。
第二个盒子行内样式写的auto,获取到就是auto字符串,并不是真正大小。
第三个盒子行内样式写的100px,但是在box-sizing值为content-box的情况下,20px的边框已经把盒子撑的宽度超过100px,但是获取的还是100px

你行内样式写的是什么,获取的就是什么,因为他读的就是DOM树。所以在日常开发中,dom.style.····常被用做在js中赋予dom新样式,因为行内样式权重大嘛。

2. getComputedStyle(b1).width ❌

这个方法获取的是CSSOM树,就是说他获取的是在代码层面最终计算出来的元素尺寸。但是!但是根据前置知识,当box-sizing的值为content-box也就是默认值的时候,你所指定的宽度width只是内容区域的宽度,并不是最终渲染出来的宽度。这个情况下用getComputedStyle(b1).width获取的宽度就是内容区域宽度,并不是最终渲染出来的宽度。

js中获取dom尺寸【简单易懂】👌

 1. 第一个盒子,就是正常情况,获取的100px。
 2. 第二个盒子,行内样式的auto覆盖了,类样式的100px,最终也是获取到当前盒子的最终宽度。
 3. 第三个盒子,获取到的100px只是代码层面的宽度,并不是浏览器渲染出来的宽度,因为边框已经影响了渲染结果。

3.最佳实践方法看这里✔

3.1获取 内容区域 + 内边距区域 clientWidth

const box = document.querySelector(".box");
console.log("box的内容区域+内边距区域", box.clientWidth);

3.2 获取可滚动区域 scrollWidth

const box = document.querySelector(".box");
console.log("box的可滚动区域", box.scrollWidth);

那么可滚动区域什么意思呢?

包括由于 overflow 溢出而在屏幕上不可见的内容。

js中获取dom尺寸【简单易懂】👌

获取的可滚动区域宽度775px,远远超出了代码指定的width:300px。

那它获取的究竟是哪里的宽度?看下图

js中获取dom尺寸【简单易懂】👌

scrollWidth获取可滚动区域包含内边距,不包含边框。

3.3 获取内容区域 + 内边距区域 + 边框区域<包含滚动条区域>offsetWidth

const box = document.querySelector(".box");
console.log("box的内容区域+内边距区域+边框区域<包含滚动条区域>", box.offsetWidth);

这个方法看似完美,可以获取到我们想要的可视区域<我眼睛看到这个盒子的区域>尺寸, 其实他也会被CSS 的 transform 属性影响。

3.4 获取可视区域 getBoundingClientRect()

const box = document.querySelector(".box");
console.log("box的可视区域", box.getBoundingClientRect().width);

这个方法就是获取可视区域尺寸,最可靠的方法,这个方法就是获取的浏览器实际渲染到页面上的尺寸。

目录3.3的 offsetWidthgetBoundingClientRect()看着很是相似,下面是一些区别。

当元素应用了 CSS 的 transform 属性(如旋转、缩放等)时,getBoundingClientRect().width 会反映出这些变换后的实际渲染宽度,而 offsetWidth 则不会考虑这些变换,它返回的是未经过变换的原始宽度。

转载自:https://juejin.cn/post/7375072185209520140
评论
请登录