原生JS实现折叠面板

6,561 阅读2分钟

折叠面板实现效果图

在平常业务开发中产品和UI经常会把文字较多或者一些订单信息设置成卡片然后以折叠的形式展现,目的是为了让首屏的可视空间加大。

实现思路:主要是控制盒子的高度配合溢出隐藏以及添加过渡效果,便可实现折叠面板。

{
	transition: all 0.3s;   // 添加过渡效果
    	overflow: hidden;       // 超过高度的隐藏
}

进入正题,先确定结构:

<div class="mx-4 my-4 fold bg-white" id="fold_{{index}}" >      
    <!-- 折叠显示区域 -->
    <div class="fold-main d-flex jc-between ai-center mx-5" id="{{index}}">
        <span class="fold-main--title fs-lg text-grey-0">{{ time }}</span>
        <div class="fold-main--info" @click="ObtainHg(index)">
            <span class="fs-lg text-grey-0 mr-1">{{ num }}支</span>
        </div>
    </div>
    <!-- 折叠显示区域 -->

    <!-- 折叠隐藏区域 -->
    <div class="quiz mx-5 pb-5" id="main_{{index}}">
      <div>1、沉着、勇猛,有辨别,不自私。</div>
        <div>2、凡事总须研究,才会明白。</div>
    </div>
    <!-- 折叠隐藏区域 -->
</div>

动态高度主要是设置在最外层的盒子,中间两块一个是标题以显示的形式展现,另一个是主体内容以动态展示的形式呈现。

我这边设置的起始高度是 64px 隐藏区域是在 64 以下,因为设置了 overflow:hidden 所以第2块盒子就不会显示。

绑定点击事件:

bindEvent() {
   const fold = document.querySelector('.container ');
   fold.addEventListener('click', this.open.bind( this ), false );
}

这里采用的是事件委托的形式获取到当前点击的元素,有不明白的同学具体百度看看即可。

open( ev ) {
   // 获取当前点击的元素
   let tag = ev.target,
       // 获取第一个盒子的元素 -> 显示区域
       fold_hg = document.getElementById(`fold_${tag.id}`),
       // 获取第二个盒子的元素 -> 隐藏区域
       vm = document.getElementById(`main_${tag.id}`);
       
       //  如果点到隐藏区域直接退出
       if ( fold_hg == null || vm == null ) return;

       // 64代表未展开面板 如果等于64就把 显示区域的高度 + 隐藏区域的高度合并起来达到展开的效果
       if ( fold_hg.offsetHeight == 64 ) {
           fold_hg.style.height = vm.offsetHeight + tag.offsetHeight + 'px';
       } else {
           fold_hg.style.height = 64 + 'px';  // 如果不等于64则代表是打开状态 再次点击就收起
       }
}

fold_${tag.id} 代码块中出现的此语法对应的是数组的下标,折叠面板是根据数组渲染出来的,每一个面板都对应了一个下标,类似vue的 v-for 在vue中的话直接利用数据响应一改变数据的内容即可发生变化,在上面的demo中的话 需要给每个盒子标记唯一性,当我点击时我才能知道我要改变的是哪一个元素。以上代码块完成可以套用到 vue uni-app 小程序上,更改实现的语法即可。


至此文章分享结束啦!

demo仓库地址:Callapse