一种内容区高度不定的展开收起方案
作者:互联网
缘起
在日常开发中,经常会遇到有些区块内容可以展开收起的需求,例如以下这两种:
固定高度式:
非固定式:
固定式
对于内容固定,高度固定的情况,很好实现,可以一开始就显示展开/收起按钮,点击切换区块的高度即可。
非固定式
而对于内容多少不固定,最终高度也不一定的情况,则稍显复杂,难点在于:
-
- 内容未超出规定高度时,展开/收起按钮不显示
-
- 内容超出规定高度时,显示展开/收起按钮
-
- 由于内容高度不一定,当点击展开按钮时,无法确定显示高度
对于这种情况,现介绍以下实现方案
实现
<div class="box">
<div class="container" id="container">
...
</div>
<div id="button" class="button">
<span>
展开
</span>
</div>
</div>
首先,内容区块不设置高度,由内容自然撑开,但是为了在超出一定高度后隐藏超出的内容,需要设置最大高度和超出隐藏:
.container {
max-height: 90px; // 规定最高90像素
overflow: hidden; // 超出部分隐藏
}
而 展开/收起按钮则和内容区同级,
.button {
position: relative;
top:0;
text-align: center;
width: 100%;
height: 20px;
cursor: pointer;
display: none;
}
在数据加载完成后,使用以下方法获取到内容区的真实高度:
getHeightUnfold(dom) {
var fakeNode = dom.cloneNode(true);
fakeNode.style.maxHeight = '1000px';
dom.parentNode.insertBefore(fakeNode, dom);
fakeNode.style.height = 'auto';
fakeNode.style.visibility = 'hidden';
var height = fakeNode.getBoundingClientRect().height;
dom.parentNode.removeChild(fakeNode);
return height;
}
该方法实际上是
- 将内容区DOM复制了一份,然后改变了它的最大高度,并且设置为不可见,
- 然后插入到了内容区DOM的前面,通过将不可见的副本的高度设置为
auto
,就可以使用getBoundingClientRect()
API 获取到它的真实高度,也就是内容区DOM的真实高, - 获取到高度后,从DOM中移除副本
拿到真实高度后,就可以用这个高度和内容区收起时的高度(这个高度是固定的)进行对比,如果该高度大于它,则显示展开/收起按钮,否则就隐藏
let dom = document.getElementById('container');
let button = document.getElementById('button');
let domHeight = getHeightUnfold(dom);
if (domHeight > 90) {
button.style.display: 'block';
} else {
button.style.display: 'none';
}
当点击展开/收起按钮时,则改变内容区DOM 的 max-height
值就可以了,比较简单,不再赘述
标签:fakeNode,dom,高度,height,内容,收起,展开,不定 来源: https://blog.csdn.net/hjb2722404/article/details/110915685