浏览器html的DOM尺寸相关api

DOM 尺寸 API:offset / scroll / client

JavaScript 里关于元素尺寸的 API 有三组共九个:offsetWidth / offsetHeightscrollWidth / scrollHeightclientWidth / clientHeight,加上对应的 Top / Left。看起来一样,实际差别巨大。本文系统梳理一遍,带可视化图。

浏览器html的DOM尺寸相关api
浏览器html的DOM尺寸相关api
浏览器html的DOM尺寸相关api

1. offset 系列(元素本身)

offsetWidth / offsetHeight 表示元素实际占据的尺寸,包括:

  • content 宽 / 高
  • padding(上下左右)
  • border(上下左右)
  • 滚动条(如果有的话,scrollbar 也算在内)

不包括:margin、被 overflow:hidden 隐藏掉的内容。

计算公式:

offsetWidth  = 左 border + 左 padding + content 宽 + 右 padding + 右 border
offsetHeight = 上 border + 上 padding + content 高 + 下 padding + 下 border

offsetParent

element.offsetParent 返回当前元素的"最近的已定位祖先元素"(position: relative / absolute / fixed)。如果没有这样的祖先,返回 body

规则:

  • 当前元素没有任何已定位祖先 → offsetParent = body
  • 有已定位祖先 → offsetParent = 最近的那个
  • 元素本身 display: noneoffsetParent = null

offsetTop / offsetLeft

相对于 offsetParent 的偏移量。注意是相对于 offsetParent,不是相对于 viewport

const box = document.querySelector('.box');
console.log(box.offsetTop, box.offsetLeft);
// 相对于 box.offsetParent 的位置

计算公式:

offsetTop = offsetParent 的上 padding
          + 当前元素之前所有兄弟元素的 offsetHeight 之和
          + 当前元素的上 margin

2. scroll 系列(包括滚动隐藏部分)

scrollWidth / scrollHeight 表示元素的完整内容尺寸(包括被滚动条隐藏的部分)。

  • 如果元素内容没溢出:scrollWidth === clientWidth
  • 如果内容溢出(出现滚动条):scrollWidth > clientWidth,等于实际内容的总宽

例子:一个 200px 宽的 div 里塞了 800px 宽的内容(overflow: auto),那:

  • offsetWidth = 200(元素自身)
  • clientWidth = 200 - 滚动条宽度(可视区域)
  • scrollWidth = 800(完整内容)

scrollTop / scrollLeft

元素的滚动距离 —— 内容相对于可视区域顶部 / 左侧的偏移。可读可写:

// 读:获取当前滚动位置
const scrollY = element.scrollTop;

// 写:滚动到指定位置
element.scrollTop = 100;

// 平滑滚动(现代浏览器)
element.scrollTo({ top: 100, behavior: 'smooth' });

3. client 系列(可视区域,不含滚动条)

clientWidth / clientHeight可视区域的尺寸 —— content + padding,不含 border、margin、滚动条

计算公式:

clientWidth  = 左 padding + content 宽 + 右 padding  (无 border 无滚动条)
clientHeight = 上 padding + content 高 + 下 padding

clientTop / clientLeft

这俩名字误导大 —— 不是位置,而是 border 的宽度:

element.clientTop  // 上 border 宽度
element.clientLeft // 左 border 宽度

对比表

API 包含 padding 包含 border 包含 overflow 内容 包含滚动条
offsetWidth / Height
scrollWidth / Height
clientWidth / Height

实际应用场景

1. 判断元素是否在 viewport 内(用 getBoundingClientRect 更现代,但 offset 也能):

function isInViewport(el) {
    const rect = el.getBoundingClientRect();
    return rect.top >= 0 &&
           rect.left >= 0 &&
           rect.bottom <= window.innerHeight &&
           rect.right <= window.innerWidth;
}

2. 检测元素是否有滚动条:

function hasScroll(el) {
    return el.scrollHeight > el.clientHeight ||
           el.scrollWidth  > el.clientWidth;
}

3. 监听滚动到底部(无限滚动加载):

window.addEventListener('scroll', () => {
    const scrollTop  = window.scrollY || document.documentElement.scrollTop;
    const clientHeight = document.documentElement.clientHeight;
    const scrollHeight = document.documentElement.scrollHeight;

    if (scrollTop + clientHeight >= scrollHeight - 100) {
        // 距底部 100px 时触发加载下一页
        loadMore();
    }
});

更现代的方法用 IntersectionObserver:

const observer = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting) loadMore();
});
observer.observe(document.querySelector('.load-trigger'));

getBoundingClientRect (推荐用这个)

实际项目里,我更推荐 getBoundingClientRect(),它返回的 DOMRect 对象有 top / right / bottom / left / width / height / x / y 全套信息,且都相对于 viewport(不是 offsetParent),计算更直观:

const rect = element.getBoundingClientRect();
console.log(rect.top, rect.left, rect.width, rect.height);
// 相对 viewport 的位置和尺寸,小数精度

offset 系列保留下来主要是历史包袱,getBoundingClientRect 是更现代的选择。

一句话总结

  • offset* —— 元素自身完整尺寸(含 border)和相对 offsetParent 的位置
  • scroll* —— 完整内容尺寸(含被滚动隐藏的)和当前滚动距离
  • client* —— 可视内容区域(不含 border、滚动条)
  • 新代码优先用 getBoundingClientRect,简单清晰
—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

一些适用于中国大陆的CDN整理

2024-6-25 11:52:22

技术教程

编程六种算法思想

2024-7-1 14:04:31

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索