【问题标题】:Read scrollHeight of div with a display:none parent使用 display:none 读取 div 的 scrollHeight
【发布时间】:2012-12-23 06:42:41
【问题描述】:

在父 div 中有一个 div 元素,该元素被 display:none 隐藏。

  • 我将 jQuery textarea 元素转储到控制台。我看到第 0 个元素的scrollHeight 属性是88
  • 我尝试将此属性读入一个 var(使用 $(element)[0].scrollHeight$(element).prop('scrollHeight'),我得到的是 0

我还尝试在读取之前使用 jQuery 将 textarea 设置为 position: absolutedisplay: block,结果相同。

如何正确读取属性?

【问题讨论】:

  • 你应该分享你的代码,我在 Chrome 和 FF 中试过这个:console.log($("textarea"));scrollHeight = 0

标签: jquery html


【解决方案1】:

display:none时元素的大小是多少? 0px by 0px

该元素尚未在屏幕上的任何位置渲染或绘制,因此它真正占据了零像素的空间。 如果它是可见的,它占用多少空间这个问题很难回答,因为准确回答它意味着将假设变为现实。我们需要实际渲染它以获得对其大小的可靠测量。

一般来说,这涉及到:

  1. 切换 - 快速使元素可见,检查高度,并恢复原状

    切换时,您可能能够在绘制周期之间显示和撤消,但不能保证。尤其是当您要测量的元素深深嵌套在隐藏的父元素中时。

  2. 克隆 - 尽可能模拟元素的属性并在屏幕外渲染

    克隆时,元素的尺寸基于大量其他元素和围绕它的属性。根据页面的复杂性,也不能保证在屏幕外创建元素会产生与原始元素完全相同的尺寸。

以下问题中列出了几种解决方案,但大多数都遵循基本模式:

还有一个名为 jQuery.Actual (2.4KB) 的库,它抽象了其中的一些工作:

这是他们自己的Demo Page 以及堆栈片段

console.log("width: ", $("#inner").actual("width"))
console.log("height: ", $("#inner").actual("height"))
#outer, #inner {
  margin: 10px;
  padding: 10px;
}
#outer {
  background: #d1e3ef;
}
#inner {
  background: #9ebae9;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.actual/1.0.19/jquery.actual.min.js"></script>

<div id="outer" style="display:none">
  <code>#outer</code>
  <div id="inner">
    <code>#inner</code>
  </div>
</div>

【讨论】:

  • 不明白,这是一个将近 6 年的问题,您提供赏金并回答它?
  • @AlexAngelico,提供了赏金,因为我正在寻找答案,然后继续四处寻找,并认为我会分享我拼凑的东西。您真的记不起赏金,但认为更新信息仍然很有价值。
【解决方案2】:

您需要为父 div 设置 dispaly:block 属性。在使用 $(element)[0].scrollHeight 获取滚动高度后,您可以将 display:none 设置为主 div。

所以你的代码将是

$('#mainDiv').show();
// Dump html to div
// Read height
var heightOfDiv = $('#mainDiv')[0].scrollHeight
// Hide the div
$('#mainDiv').hide();

【讨论】:

  • 我相信这是可行的,并且暂时显示控件并几乎立即再次隐藏它不会对用户可见。事实上,在功能块完成之前,浏览器甚至可能不会真正尝试更新用户所看到的内容,因此实际上在为您提供所需的测量值时控件始终处于隐藏状态。
【解决方案3】:

带有display: none的元素不仅不会被显示,而且不会被DOM树处理。这就是 scrollHeight 为 0 的原因。

否则,使用visibility: hidden,该元素将不可见,但它会在 DOM 中保留其空间。所以它会有一个不同于 0 的 scrollHeight。

然后,要读取属性并隐藏元素,您可以使用$('#elementId').prop('visibility','hidden'); $('#elementId').prop('scrollHeight')

【讨论】:

  • visibility: hidden; 设置为已经是display: none; 的元素不会给你滚动高度的值,因为display: none; 会优先考虑,不是吗?
  • display: none; 优先,因为它会影响 DOM 结构。 visibility: hidden; 不影响 DOM 结构,就像设置颜色或不透明度等属性。
【解决方案4】:

不,很遗憾这是不可能的。

我建议您阅读以下链接:MDN | DisplayArticle from nomensa,它们唤起了 DOM 可访问性和可见性的概念。 事实上,如果你把一个元素放到“display: none”中,它是不可见的,会退出the DOM accessibility tree。 但是,有一些技术可以让您使 DOM 元素完全不可见并且不再被认为存在于 DOM 上。

那么显然有一些技巧你一定要知道

第一个如果你想完全mask your parent div without worrying about its dimensions,我建议下面的代码。 The clip property 正在贬值,但没有它,它仍然会隐藏我们的项目。

console.log(document.getElementById('child').scrollHeight);
.hidden {
	border: 0;
	clip: rect(0 0 0 0);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
  z-index: -1;
}
<div class="hidden parent" href="#main">
  I am ignored by the DOM
  <div id="child">I am child</div>
</div>
<span style="color:red">I am the N°1</span>

否则,如果你想要to keep the dimensions of your parent div,你可以将它浮出DOM流。

console.log(document.getElementById('child').scrollHeight);
.hidden {
	height: auto;
  width: auto;
  visibility: hidden;
	position: absolute;
  z-index: -1;
}
<div class="hidden parent" href="#main">
  I am ignored by the DOM
  <div id="child">I am child</div>
</div>
<span style="color:red">I am the N°1</span>

我希望这个答案会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 2014-02-05
    相关资源
    最近更新 更多