JS 中 offsetHeight/scrollHeight/clientHeight 的区别

简介: client* clientWidth/clientHeight 返回的是元素的内部宽度,它的值只包含 content + padding,如果有滚动条,不包含滚动条 clientTop 返回的是上边

JS 基于 DOM 对象可以拿到元素的宽高的属性有 offset 系、scroll 系、client 系(以其名称作为前缀得名),IDE 提示如下(以 VS Code 为准)

接下来就以如下顺序介绍一下这三种获取宽高的方法,以及它们的不同

  1. client*
  2. offset*
  3. scroll*

client

  1. client*

    1. clientWidth/clientHeight 返回的是元素的内部宽度,它的值只包含 content + padding,如果有滚动条,不包含滚动条
    2. clientTop 返回的是上边框的宽度
    3. clientLeft 返回的左边框的宽度
<body>
  <div class="demo" style="height: 100px; width: 100px; padding: 10px;"></div>
</body>
<script>
  const div = document.querySelector(".demo");
  console.log(div.clientWidth, div.clientHeight, div.clientTop, div.clientLeft);
  // 120 120 10 10
</script>

可能有人想问了,clientBottom 是不是就是 border 底部的值呢?实际上结果是 undefiend 因为并没有这个值,clientRight 同理

注意一个小细节

clientHeightclientWidth 不包括滚动条,如果有滚动条,那么 clientHeight = content + padding - scroll (元素内容本身的高度加上内边距再减去水平滚动条的高度)

<body>
  <div
    class="demo"
    style="
      height: 100px;
      width: 100px;
      padding: 10px;
      border: 10px solid black;
      overflow: auto;
    "
  >
    <div style="height: 200px"></div>
  </div>
</body>
<script>
  const div = document.querySelector(".demo");
  console.log(div.clientWidth, div.clientHeight); // 103 120
  // 此时滚动条宽度为 17px
</script>

offset

  1. offset*

    1. offsetWidth/offsetHeight 返回的是元素的布局宽度,它的值包含 content + padding + border 包含了滚动条
    2. offsetTop 返回的是当前元素相对于其 offsetParent 元素的顶部的距离
    3. offsetLeft 返回的是当前元素相对于其 offsetParent 元素的左部的距离

不过有点奇怪的是,VS CodeWebStorm 都没有对 offset* 做任何提示(希望评论区能够给出答案)

依旧是上面的例子

<body>
  <div style="height: 100px"></div>
  <div
    class="demo"
    style="
      height: 100px;
      width: 100px;
      padding: 10px;
      border: 10px solid black;
      overflow: auto;
    "
  >
    <div style="height: 200px"></div>
  </div>
</body>
<script>
  const div = document.querySelector(".demo");
  console.log(div.offsetHeight, div.offsetWidth, div.offsetTop, div.offsetLeft);
  // 140 140 108 8
</script>

此时 divoffsetParent 就是 body

scroll

  1. scroll*

    1. scrollWidth/scrollHeight 返回值包含 content + padding + 溢出内容的尺寸
    2. scrollTop 属性返回的是一个元素的内容垂直滚动的像素数
    3. scrollLeft 读写元素左侧已滚动的距离,即位于元素左边界与元素中当前可见内容的最左端之间的距离。

scrollWidth/Height 不多讲了,和 offset 差不多以及 client 系差不多,接下来用两个动图介绍一下 scrollTopscrollLeft

scrollLeft 的数值就是已经滑动、消失的部分和当前可见区域最左边的距离

代码如下

<body>
  <div
    class="demo"
    style="
      transform: translate(0, 0);
      height: 200px;
      width: 200px;
      padding: 10px;
      border: 10px solid black;
      overflow: auto;
    "
  >
    <div style="height: 50px; width: 800px; background: black"></div>
    <div class="count" style="position: sticky; left: 0">scrollLeft: 0</div>
  </div>
</body>
<script>
  const div = document.querySelector(".demo");
  const count = document.querySelector(".count");
  div.addEventListener("scroll", () => {
    count.innerHTML = "scrollLeft: " + parseInt(div.scrollLeft);
  });
</script>

参考资料

  1. JS scrollLeft和scrollTop属性:读写元素左侧和顶部已滚动的距离
  2. 浅谈JS各种宽高(clientHeight、scrollHeight、offsetHeight等)- CSDN - 骆小胖
相关文章
|
20天前
|
存储 JavaScript 索引
js开发:请解释什么是ES6的Map和Set,以及它们与普通对象和数组的区别。
ES6引入了Map和Set数据结构。Map的键可以是任意类型且有序,与对象的字符串或符号键不同;Set存储唯一值,无重复。两者皆可迭代,支持for...of循环。Map有get、set、has、delete等方法,Set有add、delete、has方法。示例展示了Map和Set的基本操作。
23 3
|
21天前
|
JavaScript 前端开发
js开发:请解释原型继承和类继承的区别。
JavaScript中的原型继承和类继承用于共享对象属性和方法。原型继承通过原型链实现共享,节省内存,但不支持私有属性。
19 0
|
3天前
|
移动开发 JavaScript 前端开发
uni-app和Vue.js二者之间有什么区别?
1. uni-app是一个使用Vue.js开发所有前端应用的框架,支持一次编译多端运行。开发者编写的基础代码只需进行一次编写,就可以发布到多个平台,包括App、H5、微信小程序等。 2. Vue.js是一个渐进式JavaScript框架,用于构建用户界面。与其他大型框架不同的是,Vue被设计为可以自底向上逐层应用。
4 0
|
3天前
|
Web App开发 JavaScript 前端开发
Ecmascript 和javascript的区别
Ecmascript 和javascript的区别
8 0
|
5天前
|
JavaScript 前端开发
JS中浅拷贝和深拷贝的区别,浅拷贝的危害
JS中浅拷贝和深拷贝的区别,浅拷贝的危害
11 0
|
14天前
|
前端开发 JavaScript
【Web 前端】 js中call、apply、bind有什么区别?
【4月更文挑战第22天】【Web 前端】 js中call、apply、bind有什么区别?
【Web 前端】 js中call、apply、bind有什么区别?
|
14天前
|
存储 前端开发 JavaScript
【Web 前端】JS数据类型有哪些?区别?
【4月更文挑战第22天】【Web 前端】JS数据类型有哪些?区别?
|
14天前
|
JavaScript 前端开发 数据安全/隐私保护
【专栏】JavaScript中的`==`和`===`运算符有重要区别,本文将从三个部分详细探讨
【4月更文挑战第29天】JavaScript中的`==`和`===`运算符有重要区别。`==`进行类型转换后比较,而`===`不转换类型,要求完全相等。在比较对象时,`==`只比较引用,`===`比较内容。推荐使用`===`以确保准确性,但在需要类型转换时可谨慎使用`==`。注意特殊值如`null`和`undefined`的比较。在数据验证、类型判断和条件判断等场景中,应根据需求选择合适的运算符。理解两者差异能提升代码质量和稳定性。
|
14天前
|
JavaScript 前端开发
【专栏】Javascript 对象的深浅拷贝的区别以及如何实现它们
【4月更文挑战第29天】JavaScript中的对象拷贝分为浅拷贝和深拷贝。浅拷贝仅复制对象引用,修改拷贝会影响原始对象,如使用直接赋值、`Object.assign()`、扩展运算符和`Array.prototype.concat()`。深拷贝则创建独立副本,修改不影响原始对象,可通过递归、`JSON.stringify()`和`JSON.parse()`、Lodash的`cloneDeep()`或jQuery的`jQuery.extend()`实现。
|
17天前
|
JavaScript 前端开发
js的let、const、var的区别以及应用案例
【4月更文挑战第27天】ES6 中,`let` 和 `const` 是新增的变量声明关键字,与 `var` 存在显著差异。`let` 允许重新赋值,而 `const` 不可,且两者都具有块级作用域。`var` 拥有函数级作用域,并可在函数内任意位置访问。`let` 和 `const` 声明时必须初始化,而 `var` 不需。根据需求选择使用:局部作用域用 `let`/`const`,全局或函数范围用 `var`,不可变值用 `const`。
24 2