[英]offsetHeight, clientHeight and scrollHeight does not give the correct height
I've read about offsetHeight , clientHeight and scrollHeight .我读过offsetHeight 、 clientHeight和scrollHeight 。 Still I can't figure out how to set the correct height to a div that can include:
我仍然无法弄清楚如何将正确的高度设置为可以包括的 div:
In my example below I've made 4 sections.在下面的示例中,我制作了 4 个部分。 The first section is untouched so the height on that one is auto and correct.
第一部分未触及,因此该部分的高度是自动且正确的。 When I try to set the height in the other sections with offsetHeight, clientHeight and scrollHeight the results are no longer correct.
当我尝试使用 offsetHeight、clientHeight 和 scrollHeight 设置其他部分的高度时,结果不再正确。
How can I calculate it in a way that it's always working?如何以始终有效的方式计算它? I've seen many answers here on Stackoverflow but no reliable solution.
我在 Stackoverflow 上看到了很多答案,但没有可靠的解决方案。
window.addEventListener('DOMContentLoaded', (event) => { let items1 = document.querySelectorAll('.section1 div'); let items2 = document.querySelectorAll('.section2 div'); let items3 = document.querySelectorAll('.section3 div'); items1.forEach((item) => { item.style.height = item.offsetHeight + 'px'; }); items2.forEach((item) => { item.style.height = item.clientHeight + 'px'; }); items3.forEach((item) => { item.style.height = item.scrollHeight + 'px'; }); });
.div1 { border: 5px solid #fff; padding: .5rem; margin: .5rem; box-sizing: border-box; }.div2 { border: 5px solid #fff; padding: .5rem; margin: .5rem; }.div3 { padding: .5rem; margin: .5rem; box-sizing: border-box; }.div4 { padding: .5rem; margin: .5rem; }.div5 { } div[class^=div] { background: #eee; outline: 1px solid red; } body { display: flex; } section { background: #f5f5f5; margin: .5rem; width: 100px; }
<section class="correct"> <div class="div1">Some<br>text</div> <div class="div2">Some<br>text</div> <div class="div3">Some<br>text</div> <div class="div4">Some<br>text</div> <div class="div5">Some<br>text</div> </section> <section class="section1"> <div class="div1">Some<br>text</div> <div class="div2">Too<br>High</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section> <section class="section2"> <div class="div1">Too<br>low</div> <div class="div2">Too<br>high</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section> <section class="section3"> <div class="div1">Too<br>low</div> <div class="div2">Too<br>high</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section>
The issue is that you are randomly applying the box-sizing
.问题是您随机应用
box-sizing
。 You should apply them to all the elements inside the same section or not at all but not to only few of them.您应该将它们应用于同一部分中的所有元素,或者根本不应用它们,但不能只应用于其中的几个元素。
The correct result is the first one with box-sizing:border-box
applied.正确的结果是第一个应用了
box-sizing:border-box
结果。
window.addEventListener('DOMContentLoaded', (event) => { let items1 = document.querySelectorAll('.section1 div'); let items2 = document.querySelectorAll('.section2 div'); let items3 = document.querySelectorAll('.section3 div'); items1.forEach((item) => { item.style.height = item.offsetHeight + 'px'; }); items2.forEach((item) => { item.style.height = item.clientHeight + 'px'; }); items3.forEach((item) => { item.style.height = item.scrollHeight + 'px'; }); });
.div1 { border: 5px solid #fff; padding: .5rem; margin: .5rem; }.div2 { border: 5px solid #fff; padding: .5rem; margin: .5rem; }.div3 { padding: .5rem; margin: .5rem; }.div4 { padding: .5rem; margin: .5rem; } div[class^=div] { background: #eee; outline: 1px solid red; } body { display: flex; } section { background: #f5f5f5; margin: .5rem; width: 100px; }.section1 >*{ box-sizing: border-box; }
<section class="correct"> <div class="div1">Some<br>text</div> <div class="div2">Some<br>text</div> <div class="div3">Some<br>text</div> <div class="div4">Some<br>text</div> <div class="div5">Some<br>text</div> </section> <section class="section1"> <div class="div1">Some<br>text</div> <div class="div2">Too<br>High</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section> <section class="section2"> <div class="div1">Too<br>low</div> <div class="div2">Too<br>high</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section> <section class="section3"> <div class="div1">Too<br>low</div> <div class="div2">Too<br>high</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section>
Adding box-sizing
to the other will make them smaller because both don't include the border in the calculation and the value given will later include the border.将
box-sizing
添加到另一个将使它们更小,因为两者都不包括边界在计算中,并且给定的值稍后将包括边界。
window.addEventListener('DOMContentLoaded', (event) => { let items1 = document.querySelectorAll('.section1 div'); let items2 = document.querySelectorAll('.section2 div'); let items3 = document.querySelectorAll('.section3 div'); items1.forEach((item) => { item.style.height = item.offsetHeight + 'px'; }); items2.forEach((item) => { item.style.height = item.clientHeight + 'px'; }); items3.forEach((item) => { item.style.height = item.scrollHeight + 'px'; }); });
.div1 { border: 5px solid #fff; padding: .5rem; margin: .5rem; }.div2 { border: 5px solid #fff; padding: .5rem; margin: .5rem; }.div3 { padding: .5rem; margin: .5rem; }.div4 { padding: .5rem; margin: .5rem; } div[class^=div] { background: #eee; outline: 1px solid red; } body { display: flex; } section { background: #f5f5f5; margin: .5rem; width: 100px; }.section1 >*, .section2 >*, .section3 >*{ box-sizing: border-box; }
<section class="correct"> <div class="div1">Some<br>text</div> <div class="div2">Some<br>text</div> <div class="div3">Some<br>text</div> <div class="div4">Some<br>text</div> <div class="div5">Some<br>text</div> </section> <section class="section1"> <div class="div1">Some<br>text</div> <div class="div2">Too<br>High</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section> <section class="section2"> <div class="div1">Too<br>low</div> <div class="div2">Too<br>high</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section> <section class="section3"> <div class="div1">Too<br>low</div> <div class="div2">Too<br>high</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section>
Note that scrollHeight
and clientHeight
are the same here since there is no overflow.注意
scrollHeight
和clientHeight
在这里是一样的,因为没有溢出。
Typically,
offsetHeight
is a measurement in pixels of the element's CSS height, including any borders, padding, and horizontal scrollbars (if rendered).通常,
offsetHeight
是元素的 CSS 高度的像素测量值,包括任何边框、填充和水平滚动条(如果呈现)。 ref参考
The
scrollHeight
value is equal to the minimum height the element would require in order to fit all the content in the viewport without using a vertical scrollbar.scrollHeight
值等于元素需要的最小高度,以便在不使用垂直滚动条的情况下适应视口中的所有内容。 The height is measured in the same way asclientHeight
: it includes the element's padding, but not its border, margin or horizontal scrollbar (if present).高度的测量方式与
clientHeight
相同:它包括元素的填充,但不包括其边框、边距或水平滚动条(如果存在)。 It can also include the height of pseudo-elements such as::before or::after.它还可以包括伪元素的高度,例如::before 或::after。 If the element's content can fit without a need for vertical scrollbar, its
scrollHeight
is equal toclientHeight
ref如果元素的内容不需要垂直滚动条就可以适应,则它的
scrollHeight
等于clientHeight
ref
UPDATE更新
If you want a generic way then you need to test the box-sizing
.如果你想要一个通用的方式,那么你需要测试
box-sizing
。 If border-box
you consider offsetHeight
, if not you consider clientHeight
minus padding:如果你考虑使用边
border-box
offsetHeight
,如果不是你考虑clientHeight
减去填充:
window.addEventListener('DOMContentLoaded', (event) => { let items = document.querySelectorAll('section:not(.correct) div'); items.forEach((item) => { var e = window.getComputedStyle(item); var b = e.boxSizing; if(b =="border-box") item.style.height = item.offsetHeight + 'px'; else var p = parseFloat(e.paddingTop) + parseFloat(e.paddingBottom); item.style.height = (item.clientHeight - p) + 'px'; }); });
.div1 { border: 5px solid #fff; padding: .5rem; margin: .5rem; box-sizing: border-box; }.div2 { border: 5px solid #fff; padding: .5rem; margin: .5rem; }.div3 { padding: .5rem; margin: .5rem; box-sizing: border-box; }.div4 { padding: .5rem; margin: .5rem; }.div5 { } div[class^=div] { background: #eee; outline: 1px solid red; } body { display: flex; } section { background: #f5f5f5; margin: .5rem; width: 100px; }
<section class="correct"> <div class="div1">Some<br>text</div> <div class="div2">Some<br>text</div> <div class="div3">Some<br>text</div> <div class="div4">Some<br>text</div> <div class="div5">Some<br>text</div> </section> <section class="section1"> <div class="div1">Some<br>text</div> <div class="div2">Too<br>High</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section> <section class="section2"> <div class="div1">Too<br>low</div> <div class="div2">Too<br>high</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section> <section class="section3"> <div class="div1">Too<br>low</div> <div class="div2">Too<br>high</div> <div class="div3">Some<br>text</div> <div class="div4">Too<br>high</div> <div class="div5">Some<br>text</div> </section>
After many tests I've figured it out.经过多次测试,我已经弄清楚了。 The solution is to use
getComputedStyle(item).getPropertyValue('height')
.解决方案是使用
getComputedStyle(item).getPropertyValue('height')
。
In the below example the first one is untouched and the second one set the height with the above.在下面的示例中,第一个未触及,第二个设置了上面的高度。
window.addEventListener('DOMContentLoaded', (event) => { let items4 = document.querySelectorAll('.section4 div'); items4.forEach((item) => { item.style.height = getComputedStyle(item).getPropertyValue('height'); }); });
.div1 { border: 5px solid #fff; padding: .5rem; margin: .5rem; box-sizing: border-box; }.div2 { border: 5px solid #fff; padding: .5rem; margin: .5rem; }.div3 { padding: .5rem; margin: .5rem; box-sizing: border-box; }.div4 { padding: .5rem; margin: .5rem; }.div5 { } div[class^=div] { background: #eee; outline: 1px solid red; } body { display: flex; } section { background: #f5f5f5; margin: .5rem; width: 100px; }
<section class="correct"> <div class="div1">Some<br>text</div> <div class="div2">Some<br>text</div> <div class="div3">Some<br>text</div> <div class="div4">Some<br>text</div> <div class="div5">Some<br>text</div> </section> <section class="section4"> <div class="div1">Some<br>text</div> <div class="div2">Not too<br>High =)</div> <div class="div3">Some<br>text</div> <div class="div4">Not too<br>high =)</div> <div class="div5">Some<br>text</div> </section>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.