我正在使用香草javascript创建自己的滚动条组件。该元素是可调整大小的,因此在调整其大小时,滚动条的最大滚动位置和大小将随之变化。
如果我以正常速度调整大小,一切都很好,但是如果我快速测试,则计算结果(大小和最大位置)会产生错误的结果,我猜是因为THE TITLE
或offsetWidth
错误
我的滚动条的渲染功能在调整大小时触发, sbv表示垂直滚动条,sbh表示水平滚动条:
offsetHeight
有人知道为什么会这样吗? TiA
答案 0 :(得分:1)
那仅仅是一个理论上的答案,因为我没有花时间来设置一个repro案例,并且因为“ 产生错误的结果”的描述有点宽泛。
我怀疑问题实际上与您的主张相反:
offsetWidth
,offsetHeight
,scrollHeight
和scrollWidth
实际上为您提供了正确的值,这意味着您可能没想到。
这些属性,为了返回正确的值,会触发对文档中元素的所有边界框的重新计算,这称为“ reflow” 。
此重排意味着您以前设置的所有CSS规则现在都已应用并处于活动状态。
所以在您的代码中,当您这样做
elem.size = content.offsetHeight / content.scrollHeight;
elem.style.height = (elem.size * 100) + "%";
elem.max = (100 - elem.size * 100) / 100 * content.offsetHeight;
第一行content.offsetHeight
的值与第三行的值可能不再相同。
var elem = document.getElementById('elem');
var content = document.getElementById('content');
console.log('before', content.offsetHeight);
elem.size = content.offsetHeight / content.scrollHeight;
elem.style.height = (elem.size * 100) + "%";
elem.max = (100 - elem.size * 100) / 100 * content.offsetHeight;
console.log('after', content.offsetHeight);
body{
height: 100vh;
}
#content,#elem {
border: 1px solid;
}
#elem {
height: 800px;
}
<div id="content">
<div id="elem"></div>
</div>
因此,不仅触发这样的多次重排对于性能而言是可怕的,而且您的计算可能确实会出错。
最好的办法是在传递变量之前先缓存所有当前值,进行所有计算,最后只设置所有新样式。
还请注意,所有这些效果最好在requestAnimationFrame
去抖器中进行,因此每个绘画帧仅发生一次。