窗口尺寸变化时调整含文本div大小的问题排查
Problem Analysis & Fix
我一眼就看出问题所在了——当你放大屏幕时,盒子的高度已经被之前的缩小操作设置成了一个较大的值,这时候scrollHeight会等于盒子当前的高度(因为内容没有超出盒子范围),所以你再把高度设置成scrollHeight等于没做任何改变,自然不会缩小。
Why This Happens
咱们拆解一下具体流程:
- 初始状态:盒子设置了固定
height:200px,如果文本内容超出这个高度,scrollHeight会大于200px。 - 缩小屏幕:文本换行变多,内容高度超过盒子固定高度,
scrollHeight升高,你把盒子高度设置成这个值,盒子被撑开以容纳全部内容。 - 放大屏幕:文本换行减少,内容实际高度变小,但盒子此时的高度已经是之前的大值,内容没有溢出,所以
scrollHeight会等于盒子当前的高度(而非内容的实际高度),设置高度为scrollHeight就不会有任何变化,盒子自然不会缩小。
The Fix
解决方法很简单:在计算scrollHeight之前,先把盒子的高度重置为auto,让它先回到内容的自然高度,然后再获取正确的scrollHeight并设置回去。修改你的reset函数即可:
function reset() { console.log('resizing'); // 先重置高度为auto,让盒子回到内容的自然高度 box.style.height = 'auto'; const scrlHeight = box.scrollHeight; console.log(`height: ${box.style.height} - scrollheight: ${scrlHeight}`); box.style.height = `${scrlHeight}px`; }
额外优化建议
- 可以去掉初始的高度设置代码,直接让
reset函数在页面加载时也执行一次,这样初始状态也能自动适应内容:
// 页面加载时执行一次reset,初始化盒子高度 window.addEventListener('load', reset);
- 如果你不需要固定高度的限制,其实直接设置
height: auto就能让盒子自动适应内容,完全不需要手动设置scrollHeight;但如果你的需求是防止防抖等待期间内容突然跳动,那当前的方案就非常合适。
完整修改后的代码
JavaScript
const box = document.getElementById('box'); window.addEventListener('resize', _.debounce(() => { console.log('debounced'); reset() }, 500)); // 页面加载时初始化盒子高度 window.addEventListener('load', reset); function reset() { console.log('resizing'); box.style.height = 'auto'; const scrlHeight = box.scrollHeight; console.log(`height: ${box.style.height} - scrollheight: ${scrlHeight}`); box.style.height = `${scrlHeight}px`; }
CSS
#box { margin: auto auto; padding: 20px; max-width: 500px; /* 去掉固定height,让初始状态由reset函数设置 */ background: lightgrey; overflow: hidden; }
HTML
<div id="box"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean non dolor nec risus cursus convallis. Sed tempor libero eu est elementum, id molestie purus cursus. Nunc pulvinar metus non ante tincidunt tempus. Proin metus mi, varius sed purus et, feugiat auctor lectus. Pellentesque elementum dui quis nunc consectetur, vitae iaculis risus laoreet. Fusce velit leo, tristique vitae faucibus eget, sagittis sed libero. Duis eleifend interdum vulputate. Vivamus vehicula commodo leo, quis rhoncus mi pharetra nec. Vivamus elementum sodales arcu nec consectetur. Nullam rhoncus risus metus, id rhoncus lacus vulputate vel. Nam sit amet egestas arcu, et ornare elit. Pellentesque fringilla volutpat urna, vel ullamcorper velit volutpat at. Pellentesque convallis tristique consequat. Etiam at diam vitae urna bibendum maximus. Nulla elementum, ex vitae tempor egestas, sem sapien pulvinar orci, et scelerisque dolor ante at nisi. Donec in urna sed est tincidunt gravida. Proin ullamcorper sed nunc et scelerisque. Mauris sit amet arcu a odio tincidunt hendrerit. In consectetur justo ipsum, vel posuere erat tincidunt vel. Nullam dignissim ornare nunc, a porttitor felis placerat in. Etiam feugiat sem sit amet tristique congue. Donec ut arcu sit amet mauris volutpat pellentesque a a felis. Quisque purus tellus, placerat in congue nec, lacinia in lectus. Nam eget ante faucibus, facilisis odio id, dignissim lorem. Vivamus porta pharetra velit a cursus. Phasellus ac volutpat ex, nec cursus sem. Pellentesque congue sem consectetur, consectetur justo at, gravida ex. Quisque est nunc, tempus sed massa sed, consequat fringilla nulla. Phasellus consectetur, velit id suscipit volutpat, mauris mi tempus augue, sit amet dapibus dolor ipsum eget dui. Vestibulum finibus lectus facilisis feugiat accumsan. Duis lectus felis, blandit et massa ut, eleifend sagittis lacus. Pellentesque imperdiet pharetra nisi eget venenatis. Nullam tincidunt leo nec sem lacinia auctor. </div>
内容的提问来源于stack exchange,提问作者physicsboy
相关产品推荐
相关产品推荐

