当一个元素的样式被设置了display: none时,它的高度相关属性值为 0。
这是因为修改display属性会触发元素的重排和重绘,而元素重排时将会重新计算它的一些属性值。被设置display: none的元素不占用文档空间,自然计算到的高度值为 0。

关于重排和重绘:重绘重排重渲染 - Icarus

隐藏元素的方式

“隐藏”元素的方式有多种,除了设置display: none以外,还有visibility: hiddenopacity: 0height: 0; overflow: hiddentransform: scale(0)等。

为什么这里我把“隐藏”加了引号?

因为上面提到的各种方式,有“真实隐藏”和“视觉隐藏”之分。这应该不难理解,比如visibility: hiddenopacity: 0虽然视觉上看不到,可元素还是在文档流中占用了位置。

视觉隐藏的元素可以直接获取到元素的高度,所以我们要解决的问题主要还是设置display: none的元素。

头脑风暴

解决问题的关键在于透彻的分析问题。

  1. 因为我们隐藏了元素,所以获取不到元素的高度。
  2. 我们想要获取“隐藏”元素的高度做一些事。
  3. 有没有一种“隐藏”元素的方式具有display: none的特征,且可以获取高度。

OK。我们找到了一种可行性探索方案,接下来只要去验证各种隐藏元素的方式应该就能解决问题了。

scrollHeight

设置overflow: hidden可以根据元素高度裁剪视区,设置height: 0; overflow: hidden虽然文档流中占用了位置,由于高度为 0,最终表现特征达到了我们期望的display: none

此时该元素clientHeightoffsetHeight为 0,但是scrollHeight是有值的。

  • scrollHeight是一个元素没有滚动条时的所有内容高度
  • 当一个元素没有滚动条时scrollHeight === offsetHeight

当你有“获取隐藏元素的高度”这个需求时,真实目地其实就是要获取一个元素没有滚动条时的所有内容高度。否则固定高度加滚动条的情况下,高度是已知的,不会产生这个需求。
也就是说scrollHeight就是我们最后想要得到的值。

case

最后,容我一猜,当你有这个需求时,也许是要实现这样的效果吧:SlideDown