解决nz-table底部固定合计栏 开启虚拟滚动后无法横向滚动

先上效果图

 

 如图 表格是可配置列的,且列是可自定义的,也就是说可以有无限列,同时由于需求限制无法做成分页,需要一次性加载全量数据,因此延展出了性能问题。

1.底部合计栏固定对齐,拖动表格的同时合计跟着一起滚动对齐

具体思路就是给表格一个固定视窗的高度,动态获取表格配置(获取每列宽度,给合计栏的每个span一个相同的宽度),css开启滚动并隐藏合计栏的滚动条,监听表格的滚动事件,当表格滚动时给合计栏一个相同的滚动

ps:注意这时候并未开启虚拟滚动,开启虚拟滚动后滚动的视窗和现在是不一样的

 <nz-table
  #productTable
  class="statistics-table"
  [nzData]="dataList"
  [nzFrontPagination]="false"
  [nzScroll]="{ x: '100vw',y: '500px' }"
  [nzShowPagination]="false"
>
.
.
.
</nz-table>

 <div  class="fixed-footer" id="fixedFooter">
       <span   *ngFor="let item of summarySettings" class="footer-item" [ngStyle]="{width: item.width}">
              {{item.summary}}
        </span>
 </div>

这是表格大概模版

定义出来后我们再去浏览器打开f12,拖动表格滚动条,找到当前在滚动的元素,那么我们可以在控制台输入这么一段代码,回车运行后控制台会打印当前正在滚动的元素

      function findscroller(element){
        element.onscroll=function () {
            console.log(element)
        }
        Array.from(element.children).forEach(findscroller)
  }
  findscroller(document.body)

那么我们找到滚动的元素是类为“pie-table-horizontal-scroll”的div块元素,我们就可以监听到这个元素,然后驱动合计栏与它保持一致的滚动

 document.getElementsByClassName('ant-table-body')[0].addEventListener('scroll', (e:any) => {
       document.getElementById('fixedFooter')!.scrollLeft = e.target.scrollLeft
  })

那我们的功能就基本实现了,还有种情况就是表格列配置填不满整张表格时(比如只配置了一列,两列),表格列会自适应,那么我们的配置宽度就不准确了,会造成合计栏偏差的情况,这种情况下我们需要去获取表格列宽

 getThCurrWidth() {
    setTimeout(() => {
      let ths = document.getElementsByTagName('th')
      for (let i = 0; i < ths.length; i++) {
        this.pickedColumnSettings[i].nzWidth = ths[i].offsetWidth;
      }
      this.loadSummarySettings()
    }, 200)
  }

//根据表格配置获取宽度的函数
  loadSummarySettings() {
    this.summarySettings = []
    interface info {
      id:number,
      fieldName: string,
      summary:any,
      width: string
    }
    this.pickedColumnSettings?.forEach(e => {
      let temp:info = {
        id:e.id,
        fieldName: e.fieldPropertyName,
        summary: '',
        width: e.nzWidth + 'px'
      }
      if(e.fieldPropertyName === 'workHours'){
        temp.summary = this.summaryObj.workHours
      }else if(e.fieldPropertyName === 'amount'){
        temp.summary = this.summaryObj.amount
      }else if(e.fieldPropertyName === 'quantity'){
        temp.summary = this.summaryObj.quantity
      }else if(e.fieldPropertyName === 'qualifiedQuantity'){
        temp.summary = this.summaryObj.qualifiedQuantity
      }else if(e.fieldPropertyName === 'unqualifiedQuantity'){
        temp.summary = this.summaryObj.unqualifiedQuantity
      }else if(e.fieldPropertyName === 'productIndex'){
        temp.summary = '合计'
      }else{
        temp.summary = '-'
      }
      this.summarySettings.push(temp)
    });
  }

那么到这里,已经实现了需求,可是测试过程中发现数据一旦变多,超过700条页面就会崩溃,table需要花巨大的性能去渲染数据,页面会卡死。那么我们给出的解决方法就是:虚拟滚动

2.虚拟滚动开启后解决横向滚动失效

开启虚拟滚动非常简单,根据ng-zoro提供的方法只要在表格的配置开启就行了,在原来的表格上稍加改动

 <nz-table
  #productTable
  class="statistics-table"
  [nzData]="dataList"
  [nzFrontPagination]="false"
  [nzScroll]="{ x: '100vw',y: '500px' }"
  [nzVirtualForTrackBy]="trackByIndex"
  [nzShowPagination]="false"
  [nzVirtualItemSize]="20"
>
.
.
.
</nz-table>

出现了新问题,横向滚动没了,了解后知道是由于虚拟滚动的特性,使用了absolute,所以没有滚动,那么我们换种思路,既然thead和tbody滚动无法滚动,那我们让整张表格滚动

在外层包裹一个div,并且把表格宽度给一个很大的值

<div class="pie-table-horizontal-scroll">
 <nz-table
  #productTable
  class="statistics-table"
  [nzData]="dataList"
  [nzFrontPagination]="false"
  [nzScroll]="{ y: '500px' }"
  [nzVirtualForTrackBy]="trackByIndex"
  [nzShowPagination]="false"
  [nzVirtualItemSize]="20"
>
.
.
.
</nz-table>
</div>

再根据具体样式做出调整

.pie-table-horizontal-scroll ::ng-deep .ant-spin-nested-loading{
 width: 5000px;
}
.pie-table-horizontal-scroll{
  overflow: auto;
}
.pie-table-horizontal-scroll ::ng-deep .nz-table-hide-scrollbar{
  overflow: hidden !important; //表头不对齐fixed
}

.fixed-footer{
  width: 100%;
  scrollbar-width: none; /* firefox */
  -ms-overflow-style: none; /* IE 10+ */
  overflow-x: scroll;
  white-space: nowrap;
}
.fixed-footer::-webkit-scrollbar{
  display: none;
}
.footer-item{
  display: inline-block;
  color: rgba(0, 0, 0, 0.85);
  font-weight: 500;
  text-align: center;
  background-color: rgb(246,248,250);
  line-height: 61px;
  height: 61px;
  vertical-align:middle;
  // border-left: 1px solid #f0f0f0;
  // border-bottom: 1px solid #f0f0f0;
  // border-right: 1px solid #f0f0f0;
}

搞定

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值