【问题标题】:Chrome returns 0 for offsetWidth of custom HTML elementChrome 为自定义 HTML 元素的 offsetWidth 返回 0
【发布时间】:2016-08-15 01:13:24
【问题描述】:

在尝试创建一个 Angular 指令以使其内容的大小适应容器的大小时,我偶然发现了以下问题:

最小的 HTML sn-p:

<my-tag id="testWidth">
  <div>some text</div>
</my-tag>

读取my-tag 的宽度时,我在Chrome 中得到0 的结果,而Firefox 返回正确的结果。在 Chrome 中,如果我将 my-tag 替换为 div,结果也是正确的。

这是我用来获取宽度的表达式:

document.getElementById('testWidth').offsetWidth

据我所知,my-tag 应该是valid custom element name。还有什么我做错了,或者这只是 Chrome 中的一个错误?

Chrome 版本:49.0.2623.112 m

jsfiddle 用于快速测试

我正在尝试了解 Chrome 的行为是否正确或者这是一个错误。

MDN documentation 说:

HTMLElement.offsetWidth 只读属性返回布局 元素的宽度。

据我所知,这并不是说这仅适用于具有块显示的元素。而且我也支持我的理解,即 Firefox 会返回我所期望的。

span 标签也可以观察到相同的行为差异,请参阅this fiddle

【问题讨论】:

标签: javascript html dom


【解决方案1】:

您需要使用 display: block 设置 my-tag 元素的样式

这是小提琴https://jsfiddle.net/Lvntyrjy/1/

【讨论】:

  • 块级元素默认填充其父元素的宽度,如果想要的结果是测量填充内容的元素的实际宽度,display:inline-block 就可以了。
  • 您可以通过指定display: block 获得 div 元素的行为。但是好的一点,如果你想根据它的内容来测量元素的宽度,display: inline-blockfloat: left 块元素就可以了。
  • 我为这个问题添加了更多背景知识。您能否指出任何说明 offsetWidth 仅适用于 block 元素的文档?
  • 我找不到任何关于自定义元素显示样式的规范。我想没有规范。 Chrome 已决定自定义元素的默认显示样式为 inline,而 Firefox 已决定为 block。具有默认样式的浏览器之间还有其他不一致之处,这就是 CSS 重置的原因。一个可以在这里找到meyerweb.com/eric/tools/css/reset,你可以看到html5元素在这个sn-p中被重置为display: block
  • 有趣的是,在 FireFox 88 中,我的自定义元素的默认计算显示是内联的,但它仍然具有有效的 offsetWidth。因此,块显示似乎不是 FireFox 提供 offsetWidth 的要求。但在 Chrome 中,Element.getBoundingClientRect() 或 Element.getClientRects() 是替代选项,无需切换显示模式。
【解决方案2】:

你也可以像这样获取自定义元素内容的宽度:

document.querySelector('custom-element').shadowRoot.querySelector('#content').offsetWidth

【讨论】:

    【解决方案3】:

    这实际上是 Chrome 浏览器的设计权衡,以优化速度和性能。好吧,总会有这样的取舍,所以你不能完全责怪 Chrome。在实际浏览中,在渲染之前获取元素的宽度和高度是很常见的,这样我们就可以规划整体布局,例如估计应该显示多少元素。一个例子是一个扁平的&lt;select&gt;,它填充了整个面板高度(如下所示)。为了确定它的size,即它应该显示的行数,我们必须将父&lt;div&gt;的高度除以其&lt;option&gt;offsetHeight(在Chrome中始终为0) .

    所以这种有计划的绘图在 Chrome 中是不可能的。您必须解决问题,例如,首先渲染元素,然后获取其offsetHeight,然后重绘该项目。火狐就没有这个问题,你随时都可以得到它的&lt;option&gt;offsetHeight

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 2017-07-31
      • 2019-12-11
      • 2023-01-19
      • 2017-06-02
      • 2014-09-20
      • 1970-01-01
      相关资源
      最近更新 更多