繁体   English   中英

分别理解offsetWidth、clientWidth、scrollWidth和-Height

[英]Understanding offsetWidth, clientWidth, scrollWidth and -Height, respectively

有StackOverflow上关于几个问题offsetWidth / clientWidth / scrollWidth (和-Height ,分别),但没有给出什么,这些价值观是全面的解释。

此外,网络上有几个来源提供了令人困惑或不正确的信息。

你能给出一个完整的解释,包括一些视觉提示吗? 另外,如何使用这些值来计算滚动条宽度?

CSS 框模型相当复杂,尤其是在滚动内容时。 虽然浏览器使用 CSS 中的值来绘制框,但如果您只有 CSS,则使用 JS 确定所有尺寸并不简单。

这就是为什么每个元素都有六个 DOM 属性为您提供方便: offsetWidthoffsetHeightclientWidthclientHeightscrollWidthscrollHeight 这些是表示当前视觉布局的只读属性,它们都是整数(因此可能会出现舍入错误)。

让我们详细介绍一下它们:

  • offsetWidth , offsetHeight :包含所有边框的可视框的大小。 可以通过添加width / height和内边距和边框来计算,如果元素有display: block
  • clientWidthclientHeight :框内容的可视部分,不包括边框或滚动条,但包括 padding 。 不能直接从 CSS 计算,取决于系统的滚动条大小。
  • scrollWidth , scrollHeight :框的所有内容的大小,包括当前隐藏在滚动区域之外的部分。 不能直接从 CSS 计算,取决于内容。

CSS2 盒子模型

试试看: jsFiddle


由于offsetWidth考虑了滚动条宽度,我们可以使用它通过公式计算滚动条宽度

scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth

不幸的是,我们可能会得到舍入错误,因为offsetWidthclientWidth总是整数,而实际大小可能是小数,缩放级别不是 1。

请注意,这

scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth

在 Chrome 中不能可靠地工作,因为 Chrome 返回的width已经减去滚动条。 (此外,Chrome 将 paddingBottom 渲染到滚动内容的底部,而其他浏览器则不会)

我创建了一个更全面和更清晰的版本,有些人可能会发现它有助于记住哪个名称对应哪个值。 我使用 Chrome Dev Tool 的颜色代码和标签对称组织以更快地进行类比:

在此处输入图片说明

  • 注 1:如果文本的方向设置为从右到左,则clientLeft还包括垂直滚动条的宽度(因为在这种情况下滚动条显示在左侧)

  • 注 2:最外面的一行代表最近定位的父元素(一个元素的position属性设置为不同于staticinitial的值)。 因此,如果直接容器不是定位元素,则该行不代表层次结构中的第一个容器,而是层次结构中更高的另一个元素。 如果没有找到定位的父元素,浏览器将把htmlbody元素作为参考


希望有人觉得它有用,只是我的 2 美分 ;)

如果您想使用 scrollWidth 来获取“真实”内容宽度/高度(因为内容可能比 css 定义的宽度/高度框大),则scrollWidth/Height 非常不可靠,因为某些浏览器似乎“移动”了 paddingRIGHT & paddingBOTTOM 如果内容太大。 然后他们将填充放在“太宽/高内容”的右侧/底部(见下图)。

==>因此,要在某些浏览器中获得真正的内容宽度,您必须从滚动宽度中减去两个填充,而在某些浏览器中,您只需要减去左填充。

我为此找到了解决方案,并想将此添加为评论,但不允许。 所以我拍了这张照片,并在“移动的填充”和“不可靠的滚动宽度”方面让它更清晰一些。 在蓝色区域中,您可以找到有关如何获得“真实”内容宽度的解决方案!

希望这有助于使事情更清楚!

在此处输入图片说明

MDN 上有一篇很好的文章解释了这些概念背后的理论: https : //developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Det​​ermining_the_dimensions_of_elements

它还解释了 boundingClientRect 的宽度/高度与 offsetWidth/offsetHeight 之间的重要概念差异。

然后,要证明理论是对还是错,您需要进行一些测试。 这就是我在这里所做的: https : //github.com/lingtalfi/dimensions-cheatsheet

它正在测试 chrome53、ff49、safari9、edge13 和 ie11。

测试结果证明该理论总体上是正确的。 对于测试,我创建了 3 个 div,每个 div 包含 10 个 lorem ipsum 段落。 一些 css 应用于它们:

.div1{
    width: 500px;
    height: 300px;
    padding: 10px;
    border: 5px solid black;
    overflow: auto;
}
.div2{
    width: 500px;
    height: 300px;
    padding: 10px;
    border: 5px solid black;
    box-sizing: border-box;
    overflow: auto;
}

.div3{
    width: 500px;
    height: 300px;
    padding: 10px;
    border: 5px solid black;
    overflow: auto;
    transform: scale(0.5);
}

结果如下:

  • div1

    • offsetWidth: 530 (chrome53, ff49, safari9, edge13, ie11)
    • 偏移高度:330(chrome53、ff49、safari9、edge13、ie11)
    • bcr.width: 530 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.height: 330 (chrome53, ff49, safari9, edge13, ie11)

    • 客户端宽度:505(chrome53、ff49、safari9)

    • 客户端宽度:508(edge13)
    • 客户端宽度:503(ie11)
    • 客户端高度:320(chrome53、ff49、safari9、edge13、ie11)

    • 滚动宽度:505(chrome53、safari9、ff49)

    • 滚动宽度:508(edge13)
    • 滚动宽度:503(ie11)
    • 滚动高度:916(chrome53,safari9)
    • 滚动高度:954 (ff49)
    • 滚动高度:922(edge13,ie11)
  • div2

    • offsetWidth: 500 (chrome53, ff49, safari9, edge13, ie11)
    • offsetHeight: 300 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.width: 500 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.height: 300 (chrome53, ff49, safari9)
    • bcr.height: 299.9999694824219 (edge13, ie11)
    • 客户端宽度:475(chrome53、ff49、safari9)
    • 客户端宽度:478(edge13)
    • 客户端宽度:473(ie11)
    • 客户端高度:290(chrome53、ff49、safari9、edge13、ie11)

    • 滚动宽度:475(chrome53、safari9、ff49)

    • 滚动宽度:478(edge13)
    • 滚动宽度:473(ie11)
    • 滚动高度:916(chrome53,safari9)
    • 滚动高度:954 (ff49)
    • 滚动高度:922(edge13,ie11)
  • div3

    • offsetWidth: 530 (chrome53, ff49, safari9, edge13, ie11)
    • 偏移高度:330(chrome53、ff49、safari9、edge13、ie11)
    • bcr.width: 265 (chrome53, ff49, safari9, edge13, ie11)
    • bcr.height: 165 (chrome53, ff49, safari9, edge13, ie11)
    • 客户端宽度:505(chrome53、ff49、safari9)
    • 客户端宽度:508(edge13)
    • 客户端宽度:503(ie11)
    • 客户端高度:320(chrome53、ff49、safari9、edge13、ie11)

    • 滚动宽度:505(chrome53、safari9、ff49)

    • 滚动宽度:508(edge13)
    • 滚动宽度:503(ie11)
    • 滚动高度:916(chrome53,safari9)
    • 滚动高度:954 (ff49)
    • 滚动高度:922(edge13,ie11)

因此,除了 edge13 和 ie11 中 boundingClientRect 的高度值(299.9999694824219 而不是预期的 300)之外,结果证实了这背后的理论是有效的。

从那里开始,这是我对这些概念的定义:

  • offsetWidth/offsetHeight:布局边框框的尺寸
  • boundingClientRect:渲染边框框的尺寸
  • clientWidth/clientHeight:布局填充框可见部分的尺寸(不包括滚动条)
  • scrollWidth/scrollHeight:布局填充框的尺寸,如果它不受滚动条的约束

注意:默认垂直滚动条的宽度在 edge13 中为 12px,在 chrome53、ff49 和 safari9 中为 15px,在 ie11 中为 17px(通过截图在 photoshop 中的测量完成,并通过测试结果证明是正确的)。

但是,在某些情况下,您的应用可能没有使用默认垂直滚动条的宽度。

因此,鉴于这些概念的定义,垂直滚动条的宽度应该等于(在伪代码中):

  • 布局尺寸:offsetWidth - clientWidth - (borderLeftWidth + borderRightWidth)

  • 渲染维度:boundingClientRect.width - clientWidth - (borderLeftWidth + borderRightWidth)

请注意,如果您不了解布局与渲染,请阅读 mdn 文章。

另外,如果您有其他浏览器(或者您想自己查看测试结果),您可以在此处查看我的测试页面: http : //codepen.io/lingtalfi/pen/BLdBdL

我的个人备忘单,包括:

DOM 元素尺寸

  • .offsetWidth / .offsetHeight
  • .clientWidth / .clientHeight
  • .scrollWidth / .scrollHeight
  • .scrollLeft / .scrollTop
  • .getBoundingClientRect()

带有小/简单/非多合一图表:)


👁 查看全尺寸: https ://docs.google.com/drawings/d/1bOOJnkN5G_lBs3Oz9NfQQH1I0aCrX5EZYPY3mu3_ROI/edit?usp=sharing

客户端宽度/高度偏移宽度/高度计算 - 使用示例css 样式的快速摘要

在此处输入图片说明

参考: https : //javascript.info/size-and-scroll

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM