js中获取DOM元素大小各属性

172 阅读3分钟

题记

写这篇文章的背景还要从一道某大厂的笔试题说起,话不多说直接上题

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .red {
            box-sizing: border-box;
            width: 200px;
            padding: 30px;
            height: 200px;
            margin: 30px;
            border: 1px solid green;
            background-color: red;
        }
    </style>
</head>

<body>
    <div class="red"></div>
     <script>
        let div = document.getElementsByClassName("red")[0];
        四个选项
        A:div.offsetWidth=200;
        B:div.clientWidth=198;
        C:div.style.width="200px";
        D:div.style.width="260px";
    </script>
</body>

</html>

对于这道题,一些对js获取元素大小和位置属性不熟悉的同学,可能就会一头雾水。所以这篇文章旨在对这些属性进行一个总结和区分,熟悉这些属性的大佬就可以绕路拉。

ps:题目答案在文章末尾。

1.获取元素大小

jsDOM中有三个属性可以获取元素的大小,但这三个属性各有差异。

1.offsetWidth

在普通盒子模型的情况下,offsetWidth包含元素的width,内边距(padding),边框(border),滚动条(如果存在的话)。

在怪异盒模型的情况下,offsetWidth只包含元素的width(content+padding+border)。

注意:该属性是一个只读属性,也就是说我们没法通过该属性来改变元素的大小,且在普通盒子模型下和怪异盒模型下有差别,这点要特别注意

image.png

2.clientWidth

在普通盒子模型的情况下,clientWidth包含元素的width,内边距(padding),不包括边框 border、外边距 margin 和滚动条

在怪异盒模型的情况下,clientWidth包含元素的width(content+padding),也就是width-border

注意:该属性是一个只读属性,也就是说我们没法通过该属性来改变元素的大小,且在普通盒子模型下和怪异盒模型下有差别,这点要特别注意

image.png

3.scrollWidth

元素在不使用滚动条的情况下适合视口中的所有内容所需的最小宽度,包括由于overflow溢出而在屏幕上不可见的内容,一般用来获取元素内容的宽度

在普通盒子模型的情况下,clientWidth包含元素的width,内边距(padding),不包括边框 border、外边距 margin 和滚动条

在怪异盒模型的情况下,clientWidth包含元素的width(content+padding),也就是width-border

例子
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .red {
            box-sizing: border-box;
            width: 200px;
            padding: 30px;
            height: 200px;
            margin: 30px;
            border: 1px solid green;
            background-color: red;
        }

        .green {
            background-color: green;
            height: 800px;
        }
    </style>
</head>

<body>
    <div class="red">
        <div class="green"></div>
    </div>
    <script>
        let div = document.getElementsByClassName("red")[0];
        console.log("offsetWidth", div.offsetWidth);
        console.log("clientWidth", div.clientWidth);
        console.log("scrollHeight", div.scrollHeight)
    </script>
</body>

</html>

1.在box-sizing:border-box的情况下

image.png 结果非常明显,在border-box的情况下,width=content+padding+border,width=200
offsetWidth=200,
clientWidth=width-border=198
scrollWidth=div.green的高度+div.red的上padding=830

2.在box-sizing:content-box也就是不设置box-sizing的情况下,

image.png offsetWidth=width+padding+border=262
clientWidth=width+padding=260
scrollWidth=div.green的高度+div.red的上padding=830

4.Element.style.width

当我们通过div.style.width去获取元素的宽度的时候,我们会发现控制台打印为空

image.png 原因是div.style.width只能获取内联样式设置的width,因为我们没有设置内联样式的width,所以获取到的width是空。
接下来我们在上面的代码加上内联样式看看结果

    <div class="red" style="width: 500px;padding: 20px;">
        <div class="green"></div>
    </div>

image.png 很明显的看出,width能够打印出width,这个width是直接拿到width的属性值,而不是盒子的大小,而且需要注意的是这个属性是带单位px的。
这个属性不同于上面的三个属性,它可以通过改变width值来改变元素的大小,也就是说它是可读的也是可写的。

    <div class="red" style="width: 500px;padding: 20px;">
        <div class="green"></div>
    </div>
    <script>
        let div = document.getElementsByClassName("red")[0];
        console.log("style.width", div.style.width);
        div.style.width = 200 + "px"
        console.log("style.width", div.style.width);
    </script>

image.png

文章写到这里,开头的笔试题答案就很明显了,直接选A和B,没有设置内联width,所以是取不到width值的。该篇文章对获取DOM元素大小的几个属性进行了简单介绍,如果想了解更多,建议可以去读一下MDN,developer.mozilla.org/zh-CN/docs/…