JavaScript中 获取DOM元素尺寸和位置

简介: JavaScript中 获取DOM元素尺寸和位置

本文案例使用的浏览器为Chrome;

1. 获取元素的 css 大小

1.1 获取元素的行内样式

<script>
  function boxInfo(){
    let box = document.getElementById('box');
    let w = box.style.width;
    let h = box.style.height;
    console.log(w,h) // 700px 800px
  }
</script>
<body>
  <div id="box" style="width: 700px;height:800px; background-color: pink;"></div>
  <button onclick="boxInfo()">测试</button>
</body>

只是将 style 属性中的值显示出来

1.2 获取计算后的样式

<style>
  #box{
    width: 700px;
    height: 800px;
    padding: 10px;
    background-color: pink;
    border: 1px solid red;
  }
</style>
<script>
  function boxInfo(){
    var style = window.getComputedStyle ? window.getComputedStyle(box,null) : null || box.currentStyle;
    let w = style.width;
    let h = style.height;
    console.log(w,h) // 700px 800px
  }
</script>
<body>
  <div id="box" ></div>
  <button onclick="boxInfo()">测试</button>
</body>

注意:如果不设置元素的宽度和高度,在非IE浏览器下返回默认的宽度和高度,在IE下面返回 auto 字符串;

1.3 获取 < link > 和 < style > 标签写入的样式

<style>
  #box{
    width: 700px;
    height: 800px;
    padding: 10px;
    background-color: pink;
    border: 1px solid red;
  }
</style>
<script>
  function boxInfo(){
    var sheet = document.styleSheets[0];
    var rule = (sheet.cssRules || sheet.rules)[0];
    let w = rule.style.width;
    let h = rule.style.height;
    console.log(w,h) // 700px 800px
  }
</script>
<body>
  <div id="box" ></div>
  <button onclick="boxInfo()">测试</button>
</body>

cssRules(或rules)只能获取到内联和链接样式的宽和高,不能获取到行内和计算后的样式。

getComputedStyle、 element.style 异同:

相同点:

返回的都是 CSSStyleDeclaration 对象,取相应属性值得时候都是采用的 CSS 驼峰式写法,均需要注意 float 属性;

不同点:


element.style 读取的只是元素的内联样式,即写在元素的 style 属性上的样式;而 getComputedStyle 读取的样式是最终样式,包括了内联样式、嵌入样式和外部样式;

element.style 既支持读也支持写,而 getComputedStyle 仅支持读并不支持写入;

我们可以通过使用 getComputedStyle 读取样式,通过 element.style 修改样式。

总结: 以上的三种 CSS 获取元素大小的方法,只能获取元素的 CSS 大小,却无法获取元素本身实际的大小。比如加上了内边距、滚动条、边框之类的。

2. 获取元素的实际大小

2.1 clientWidth 和 clientHeight

这组属性可获取元素可视区的大小,可以得到元素内容及内边距所占据的空间大小。

返回了元素大小,但没有单位,默认单位是px,如果你强行设置了单位,比 如100em之类,它还是会返回px的大小。

对于元素的实际大小,clientWidth 和 clientHeight 理解方式如下:

  • a. 增加边框,无变化;
  • b. 增加外边距,无变化;
  • c. 增加内边距,最终值等于原本大小加上内边距的大小;
  • d. 增加滚动条,最终值等于原本大小减去滚动条的大小;
<style>
  #box{
    background-color: green;
    width: 200px;
    height: 200px;
    border: solid 5px red;  /* 对应a理解,结果:200,200 */
    margin: 10px;           /* 对应b理解,结果:200,200*/
    padding: 20px;          /* 对应c理解,结果:240,240*/
    overflow: scroll;       /* 对应d理解,结果:223,223,223=200(css大小)+40(两边内边距)-17(滚动条宽度)*/
  }
</style>
<script>
  function boxInfo(){
    var box = document.getElementById("box");
    let w = box.clientWidth;
    let h = box.clientHeight;
    console.log(w,h) // 223 223
  }
</script>
<body>
  <div id="box" ></div>
  <button onclick="boxInfo()">测试</button>
</body>

注意:如果说没有设置任何CSS的宽和高度,那么非IE浏览器会算上滚动条和内边距的计算后的大小,而IE浏览器则返回0(IE8已修复)。

2.2 scrollWidth、scrollHeight


scrollWidth:返回元素的整体宽度,包括由于溢出而无法展示在网页的不可见部分;

scrollHeight :返回元素的整体高度,包括由于溢出而无法展示在网页的不可见部分;


对于元素的实际大小,scrollWidth 和 scrollHeight 理解如下:增加边框,不同浏览器有不同解释(下面在IE8中运行正常,IE6运行不正常):

a. Firefox和Opera浏览器会增加边框的大小;

b. IE、Chrome和Safari浏览器会忽略边框大小;

c. IE浏览器只显示它本来内容的高度;

增加内边距,最终值会等于原本大小加上内边距大小;

增加滚动条,最终值会等于原本大小减去滚动条大小;

增加外边距,无变化;

增加内容溢出,Firefox、Chrome和IE获取实际内容高度,Opera比前三个浏览器获取的高度偏小,Safari比前三个浏览器获取的高度偏大;

<style>
  #wrap{
    width: 200px;
    height: 200px;
    background-color: blue;
    padding: 20px;
    overflow: auto;
    border: 1px solid green; 
  }
  #box{
    width: 400px;
    height: 400px;
    padding: 10px;
    background-color: pink;
    border: 1px solid red;
    margin: 20px;                 
  }
</style>
<script>
  function boxInfo(){
    let box = document.getElementById("box");
    console.log(box.scrollWidth,box.scrollHeight) // 420 420
  }
</script>
<body>
  <div id="wrap">
    <div id="box"></div>
  </div>
  <button onclick="boxInfo()">测试</button>
</body>

2.3 offsetWidth、offsetHeight

这组属性可以返回元素实际大小,包含边框、内边距和滚动条。返回了元素大小,默认单位是 px,如果没有设置任何 CSS 的宽和高度,会得到计算后的宽度和高度。

对于元素的实际大小,offsetWidth 和 offsetHeight 理解如下:

  1. 增加边框,最终值会等于原本大小加上边框大小;
  2. 增加内边距,最终值会等于原本大小加上内边距大小;
  3. 增加外边距,无变化;
  4. 增加滚动条,无变化,不会减小;

对于元素大小的获取,一般是块级(block)元素并且以设置了CSS大小的元素较为方便。

如果是内联元素(inline)或者没有设置大小的元素就尤为麻烦,所以,建议使用的时候注意。

<style>
  #box{
    background-color: green;
    width: 200px;
    height: 200px;
    border: solid 5px red;       /*结果:210,210*/
    margin: 10px;                /*结果:210,210(无变化)*/
    padding: 20px;              /*结果:250,250*/
    overflow: scroll;          /*结果:250,250(无变化)*/
  }
</style>
<script>
  function boxInfo(){
    var box = document.getElementById("box");
    let w = box.offsetWidth;
    let h = box.offsetHeight;
    console.log(w,h) // 250 250
  }
</script>
<body>
  <div id="box" ></div>
  <button onclick="boxInfo()">测试</button>
</body>

3. 获取元素周边尺寸(位置)

3.1 clientLeft、clientTop

获取元素设置的左边框和上边框大小(未设置 返回0),目前只提供了 Left 和 Top 这组,并没有提供 Right 和 Bottom。

如果四条边宽度不同的话,可以直接通过计算后的样式获取或者采用以上三组获取元素大小的减法求得。

右边框的宽度:div.offsetWidth - div.clientWidth - div.clientLeft
底边框的宽度:div.offsetHeight - div.clientHeight - div.clientTop
<style>
  #box{
    width: 200px;
    height: 200px;
    border-top: solid 10px red;
    border-right: solid 20px #00ff00;
    border-bottom: solid 30px blue;
    border-left: solid 40px #808080;
  }
</style>
<script>
  function boxInfo(){
    var box = document.getElementById("box");
    console.log(box.clientLeft,box.clientTop) // 40 10
  }
</script>
<body>
  <div id="box" ></div>
  <button onclick="boxInfo()">测试</button>
</body>

3.2 offsetLeft、offsetTop

这组属性可以获取当前元素相对于父元素的位置。最好将它设置为定位 position:absolute,否则不同的浏览器会有不同的解释。

<style>
  #box{
    width: 200px;
    height: 200px;
    background-color: pink;
    position: absolute;        /* 将 position 设置为 absolute,则所有浏览器返回一样的值 */
    left: 30px;
    top: 20px;
    padding: 10px;            /* 30 20 加上内边距,不会影响它的位置 */
    border: 1px solid red;    /* 30 20 加上边框,不会影响它的位置 */
    margin: 50px;             /* 80 70 加上外边距,位置值会累加 */
  }
</style>
<script>
  function boxInfo(){
    var box = document.getElementById("box");
    console.log(box.offsetLeft, box.offsetTop) // 80 70
  }
</script>
<body>
  <div id="box" ></div>
  <button onclick="boxInfo()">测试</button>
</body>

3.3 scrollTop、scrollLeft

scrollLeft:读写元素左侧已滚动的距离,即位于元素左边界与元素中当前可见内容的最左端之间的距离;

scrollTop:读写元素顶部已滚动的距离,即位于元素顶部边界与元素中当前可见内容的最顶端之间的距离;

  • 这两个属性只能用于元素设置了 overflow 的 css 样式中,否者这两个属性没有任何意义,且 overflow 的值为visiblehidden,auto,scroll;
  • 对这两个参数设置值时,直接用数字就可以了,否者不起作用;
<style>
  #wrap{
    width: 300px;
    height: 300px;
    background-color: blue;
    padding: 20px;
    overflow: auto;
    border: 1px solid green; 
  }
  #box{
    width: 400px;
    height: 400px;
    background-color: pink;
    padding: 10px;    
    border: 1px solid red;    
    margin: 50px;            
  }
</style>
<script>
  function boxInfo(){
    var wrap = document.getElementById("wrap");
    wrap.scrollLeft = 100;  // 设置盒子左边滚出区域宽度为100像素
    wrap.scrollTop = 100;   // 设置盒子顶部滚出区域高度为100像素
    console.log(wrap.scrollLeft, wrap.scrollTop)  // 100 100
  }
</script>
<body>
  <div id="wrap">
    <div id="box" ></div>
  </div>
  <button onclick="boxInfo()">测试</button>
</body>

3.4 offsetParent

获取父元素;

如果本身父元素是< body >,非IE 返回 body 对象,IE(IE6)返回 html 对象;

如果两个元素嵌套,如果父元素没有使用定位 position:absolute,那么 offsetParent 将返回 body 对象或 html 对象。

所以,获取 offsetLeft 和 offsetTop 时候,CSS 定位很重要。


在很多层次里,外层已经定位,我们怎么获取里层的元素距离 body 或 html 元素之间的距离呢?

也就是获取任意一个元素距离页面上的位置。那么我们可以编写函数,通过不停的向上回溯获取累加来实现。

<style>
  #wrap{
    width: 300px;
    height: 300px;
    background-color: blue;
    padding: 20px;
    border: 1px solid green; 
    position: absolute;
    top:50px;
    left: 10px;
  }
  #box{
    width: 100px;
    height: 100px;
    background-color: pink;   
    border: 1px solid red;               
  }
</style>
<script>
  function boxInfo(){
    var box = document.getElementById("box");
    var left = box.offsetLeft;          // 得到第一层距离
    var parent = box.offsetParent;     // 得到第一个父元素
    while (parent !== null) {         // 如果还有上一层父元素
      left += parent.offsetLeft;      // 把本层的距离累加
      parent = parent.offsetParent;  // 得到本层的父元素
    }
    console.log(left) // 30
    return left;
  }
</script>
<body>
  <div id="wrap">
    <div id="box"></div>
  </div>
  <button onclick="boxInfo()">测试</button>
</body>

3.5 getBoundingClientRect()

语法:

domRect = element.getBoundingClientRect();

返回一个矩形对象,包含四个属性:left、top、right 和 bottom,分别表示元素各边与页面上边和左边的距离。

2020062310470442.png

注意: IE、Firefox3+、Opera9.5、Chrome、Safari支持。在IE中,默认坐标从(2,2)开始计算,导致最终距离比其他浏览器多出两个像素,我们需要做个兼容。

<style>
  *{
    margin:0px;
  }
  #box{
    width: 100px;
    height: 100px;
    padding: 10px;
    margin: 10px;
    background-color: pink;   
    border: 1px solid red;               
  }
</style>
<script>
  function boxInfo(){
    let box = document.getElementById("box");
    let top = box.getBoundingClientRect().top;           // 元素上边距离页面上边的距离
    let bottom = box.getBoundingClientRect().bottom;     // 元素下边距离页面上边的距离
    let left = box.getBoundingClientRect().left;         // 元素左边距离页面左边的距离
    let right = box.getBoundingClientRect().right;       // 元素右边距离页面左边的距离
    console.log(top,bottom,left,right) // 10 132 10 132
  }
</script>
<body>
  <div id="box"></div>
  <button onclick="boxInfo()">测试</button>
</body>




相关文章
|
28天前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
14天前
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
15天前
|
JavaScript 前端开发 开发者
.js的dom元素操作
【10月更文挑战第29天】通过灵活运用这些 DOM 元素操作方法,JavaScript 可以实现丰富的网页交互效果,如动态更新页面内容、响应用户操作、创建和删除页面元素等。在实际开发中,开发者可以根据具体的需求和场景,选择合适的 DOM 元素操作方法来实现所需的功能,为用户提供更加流畅和动态的网页体验。
|
15天前
|
JavaScript 前端开发
|
1月前
|
移动开发 JavaScript 前端开发
原生js如何获取dom元素的自定义属性
原生js如何获取dom元素的自定义属性
48 4
|
1月前
|
JavaScript
js删除数组中已知下标的元素
js删除数组中已知下标的元素
35 4
|
15天前
|
JavaScript 前端开发 API
|
1月前
|
JavaScript 前端开发 容器
js之dom学习
js之dom学习
35 0
|
1月前
|
JavaScript
DOM 节点列表长度(Node List Length)
DOM 节点列表长度(Node List Length)
|
27天前
|
JavaScript
HTML DOM 节点树
HTML DOM 节点是指在 HTML 文档对象模型中,文档中的所有内容都被视为节点。整个文档是一个文档节点,每个 HTML 元素是元素节点,元素内的文本是文本节点,属性是属性节点,注释是注释节点。DOM 将文档表示为节点树,节点之间有父子和同胞关系。