我有几百个这样的“行”元素:
<div class='row'>
<div class='cell'></div>
<div class='cell'></div>
<div class='cell'></div>
</div>
在它们已经呈现在页面上之后,我需要获取他们的clientHeight。我知道“clientHeight”属性会强制重排,这会影响我的性能,因为它们太多了。但是-它们已经被渲染了,我知道它们的大小在渲染时间和我查询它们的高度之间不会改变。
有没有一种方法可以告诉浏览器在查询高度时不进行重排?
此外-Webkit检查器说:
Layout tree size 5901
Layout scope Whole document
而且div位于绝对定位的祖先中-不应该仅对绝对定位的元素进行重排吗?
编辑:
因此,提供的答案是正确的。我实际上是在弄脏布局,因为我有这个循环:
rows.each(function(){
$(this).css('height', this.clientHeight);
});
将代码更改为此可解决问题:
var heights = rows.map(function(){
return this.clientHeight;
});
rows.each(function(){
$(this).css('height', heights.shift());
});
最佳答案
clientHeight属性不会强制进行重排,至少不会单独进行重排。您需要两件事来触发重排:
您可以轻松地批量调用以设置宽度或高度,并且在JS上下文放弃控件之前不会发生重排。您可以轻松地对布局属性进行批处理查询,如果当前布局不脏,则不会发生重排。
当您连续执行1和2时,会出现问题。为了使您的查询获得准确的信息,必须进行重排。
据我所知,您有一个正确定位的祖先应该限制从整个文档“散布”整个流程的回流(绝对定位的祖先的父代将不会重排)。绝对定位的祖先内的所有项目仍将回流!
至于您的问题的解决方案,是的。设置一个缓存机制,如下所示(伪代码):
forEachDiv(function(div) {
div.getClientHeight = function(){
return div.cachedClientHeight = div.cachedClientHeight || div.clientHeight;
}
});
然后,您可以根据需要多次使用
div.getClientHeight()
而不是div.clientHeight
,只有第一次使用才会触发重排(如果脏了)。显然,与第一个建议保持一致,您也可以人为地查询clientHeight来一次批处理所有div(=一个重排),此后就没有更多问题了。
// cache the client height for all divs now, to avoid reflows later
forEachDiv(function(div) {
div.getClientHeight();
});