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>




相关文章
|
JavaScript 算法 开发者
如何用JS实现在网页上通过鼠标移动批量选择元素的效果?
本文介绍了类似电脑桌面通过鼠标选择多个图标的实现原理。主要通过监听mousedown、mousemove和mouseup事件,动态调整选择框大小并计算与元素的重叠情况。提供了角重叠和相交重叠的检测方法,并附有示例代码和在线演示链接,方便开发者参考与测试。
513 56
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
776 1
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
移动开发 运维 供应链
通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
array.some()可以用来权限检查、表单验证、库存管理、内容审查和数据处理等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
供应链 JavaScript 前端开发
通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
array.every()可以用来数据验证、权限检查、一致性检查等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
1182 5
|
JavaScript 前端开发 开发者
.js的dom元素操作
【10月更文挑战第29天】通过灵活运用这些 DOM 元素操作方法,JavaScript 可以实现丰富的网页交互效果,如动态更新页面内容、响应用户操作、创建和删除页面元素等。在实际开发中,开发者可以根据具体的需求和场景,选择合适的 DOM 元素操作方法来实现所需的功能,为用户提供更加流畅和动态的网页体验。
|
JavaScript 前端开发 API
|
Web App开发 前端开发 JavaScript
JavaScript中尺寸、坐标
测试环境是IE8,Chrome38,Firefox40,下面是全局通用脚本打印代码
JavaScript中尺寸、坐标

热门文章

最新文章