el-table表头根据内容自适应完美解决表头错位和固定列错位


Posted in Javascript onJanuary 07, 2021

将代码复制到指令中即可使用。通过指令方式进行调用。(使用方式 <el-table v-tableFit></el-table>)

通过计算文字的宽度进行表头设置,其他内容无法计算。

5000个单元格以上根据实际情况使用以上根据实际情况使用,因为单元格越多,计算时间越长。

尽量使用v-if,不然有些情况下会计算错误。

Vue.directive("tableFit", {
 //指令所在组件的 VNode 及其子 VNode 全部更新后调用。
 componentUpdated(el, binding, vnode) {
  setTimeout(() => {
   adjustColumnWidth(el, vnode);
  }, 0)
 },
});

function adjustColumnWidth(table, vnode) {
 //中文和全角正则
 const CN = new RegExp("[\u4E00-\u9FA5]|[^\uFF00-\uFFFF]");
 const NUM = new RegExp("[0-9]");
 //中文字体的像素宽度比例
 const CN_RATE = 1.1
 //数字字体的像素宽度比例
 const NUM_RATE = 0.65
 //其他字体的像素宽度比例
 const OTHER_RATE = 0.5
 
 const columns = vnode.child.columns.slice()
 //el-table通过colgroup标签设置html宽度
 const colgroup = table.querySelector("colgroup");
 const colDefs = [...colgroup.querySelectorAll("col")];
 //忽略 设置了宽度 序号 多选框 的列
 //判断gutter是否已存在
 const gutter = colgroup.querySelector(`col[name=gutter]`)
 const gutterx = colgroup.querySelector(`col[name=gutterx]`)
 let except = 0
 if (gutter || gutterx) {
  //删除gutter
  colDefs.pop()
 }
 //若有序号 多选框则删除
 except = colDefs.length - columns.length
 colDefs.splice(0, except)
 for (let i = columns.length - 1; i >= 0; i--) {
  if (columns[i].width) {
   colDefs.splice(i, 1)
   columns.splice(i, 1)
  }
 }

 //设置每列宽度
 colDefs.forEach((col, index) => {
  //colgroup中 和 表头标签的class名相同 通过class寻找相同列
  const clsName = col.getAttribute("name");
  const cells = [
   ...table.querySelectorAll(`.el-table__body-wrapper td.${clsName}`),
   ...table.querySelectorAll(`th.${clsName}`),
  ];
  const widthList = cells.map((el) => {
   const cell = el.querySelector(".cell")
   if (cell) {
    let fontSize = parseInt(window.getComputedStyle(cell,null).fontSize)
    fontSize = fontSize ? fontSize : 14
    let width = 0
    //计算每个字符的宽度
    for(let str of cell.innerText) {
     if(CN.test(str)) {
      width += fontSize * CN_RATE
     }else if(NUM.test(str)) {
      width += fontSize * NUM_RATE
     }else {
      width += fontSize * OTHER_RATE
     }
    }
    return Math.ceil(width)
   } else {
    return 0
   }
  });
  
  //取一列中的最大宽度
  const max = Math.max(...widthList);
  if (max !== 0) {
   //在表格数据中设置minWidth 防止尺寸变化重新计算原来的宽度
   //20 + 2  20 是cell类的padding 2 是给予额外空间
   columns[index].minWidth = max + 22
   table.querySelectorAll(`col[name=${clsName}]`).forEach((el) => {
    el.setAttribute("width", max + 22);
   });
  }
 });

 //设置完后调用el-table方法更新布局
 vnode.child.doLayout()

 tableRevise(table)
}

修正表格表头,固定列错位

没有错位的可以忽略

//修正el-table错位
function tableRevise(table) {
 const tableWrapper = table.querySelector('.el-table__body-wrapper')
 const tableBody = table.querySelector('.el-table__body')
 const colgroup = table.querySelector("colgroup");
 /**
  * (以下数值为滚动条高度,可以自己根据情况通过class重新修改)
  */
 //内容大于容器时
 if (tableBody.clientWidth > tableWrapper.offsetWidth) {
  
  //设置x轴滚动
  tableWrapper.style.overflowX = 'auto'
  //解决固定列错位 (没有错位的可以忽略以下内容)
  let fixedWrap = table.querySelectorAll('.el-table .el-table__fixed-body-wrapper')
  if (fixedWrap.length > 0) {
   fixedWrap.forEach(item => {
    item.style.paddingBottom = 8 + 'px'
   })
  }
  //解决固定列覆盖滚动条
  let fixed_left = table.querySelector('.el-table .el-table__fixed')
  let fixed_right = table.querySelector('.el-table .el-table__fixed-right')
  if (fixed_left) {
   fixed_left.style.height = 'calc(100% - 8px)'
  }
  if (fixed_right) {
   fixed_right.style.height = 'calc(100% - 8px)'
  }
  //解决表头偏移
  //没有原生的gutter时自己新增一个
  const gutter = colgroup.querySelector(`col[name=gutter]`)
  const gutterx = colgroup.querySelector(`col[name=gutterx]`)
  if (!gutter && !gutterx) {
   let col = document.createElement('col')
   col.setAttribute('name', 'gutterx')
   col.setAttribute('width', '8')
   colgroup.appendChild(col)
  }
 }
}

到此这篇关于el-table表头根据内容自适应完美解决表头错位和固定列错位 的文章就介绍到这了,更多相关el-table 自适应内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木! 

Javascript 相关文章推荐
基于jquery.Jcrop的头像编辑器
Mar 01 Javascript
基于Jquery的仿照flash放大图片效果代码
Mar 16 Javascript
超赞的动手创建JavaScript框架的详细教程
Jun 30 Javascript
推荐阅读的js快速判断IE浏览器(兼容IE10与IE11)
Dec 13 Javascript
Vue制作Todo List网页
Apr 26 Javascript
详解vue过滤器在v2.0版本用法
Jun 01 Javascript
vue中for循环更改数据的实例代码(数据变化但页面数据未变)
Sep 15 Javascript
前端html中jQuery实现对文本的搜索功能并把搜索相关内容显示出来
Nov 14 jQuery
vue项目动态设置页面title及是否缓存页面的问题
Nov 08 Javascript
浅谈redux, koa, express 中间件实现对比解析
May 23 Javascript
JS实现省市县三级下拉联动
Apr 10 Javascript
解决父组件将子组件作为弹窗调用只执行一次created的问题
Jul 24 Javascript
vue3中轻松实现switch功能组件的全过程
Jan 07 #Vue.js
vue+elementui通用弹窗的实现(新增+编辑)
Jan 07 #Vue.js
微信小程序onShareTimeline()实现分享朋友圈
Jan 07 #Javascript
JavaScript实现滑块验证解锁
Jan 07 #Javascript
js删除指定位置超链接中含有百度与360的标题
Jan 06 #Javascript
基于element-ui封装表单金额输入框的方法示例
Jan 06 #Javascript
JS中多层次排序算法的实现代码
Jan 06 #Javascript
You might like
PHP中把stdClass Object转array的几个方法
2014/05/08 PHP
PHP多个文件上传到服务器实例
2014/10/29 PHP
Yii2 rbac权限控制之rule教程详解
2016/06/23 PHP
完美解决JS中汉字显示乱码问题(已解决)
2006/12/27 Javascript
如何让动态插入的javascript脚本代码跑起来。
2007/01/09 Javascript
用cssText批量修改样式
2009/08/29 Javascript
同时使用n个window onload加载实例介绍
2013/04/25 Javascript
JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)
2014/08/16 Javascript
控制台报错object is not a function的解决方法
2014/08/24 Javascript
js仿QQ中对联系人向左滑动、滑出删除按钮的操作
2016/04/07 Javascript
JavaScript实现url参数转成json形式
2016/09/25 Javascript
bootstrap 模态框(modal)实现水平垂直居中显示
2017/01/23 Javascript
基于JavaScript实现图片剪切效果
2017/03/07 Javascript
用react-redux实现react组件之间数据共享的方法
2018/06/08 Javascript
利用vue-i18n实现多语言切换效果的方法
2019/06/19 Javascript
Nodejs 识别图片类型的方法
2019/08/15 NodeJs
浅谈Python使用Bottle来提供一个简单的web服务
2017/12/27 Python
儿童python练习实例
2018/05/27 Python
Python3实现转换Image图片格式
2018/06/21 Python
浅析Django中关于session的使用
2019/12/30 Python
基于PyQT实现区分左键双击和单击
2020/05/19 Python
详解Python设计模式之策略模式
2020/06/15 Python
Python爬虫+Tkinter制作一个翻译软件的示例
2021/02/20 Python
Vrbo西班牙:预订您的度假公寓(公寓、乡村房屋…)
2020/04/27 全球购物
大专学生推荐信范文
2013/11/19 职场文书
机电一体化应届生求职信范文
2014/01/24 职场文书
公开服务承诺制度
2014/03/26 职场文书
小学师德标兵先进事迹材料
2014/05/25 职场文书
2014会计年终工作总结
2014/12/20 职场文书
事业单位年度考核个人总结
2015/02/12 职场文书
辞职信范文大全
2015/03/02 职场文书
无婚姻登记记录证明
2015/06/18 职场文书
导游词之上海东方明珠塔
2019/09/25 职场文书
不同品牌、不同型号对讲机如何互相通联
2022/02/18 无线电
使用python创建股票的时间序列可视化分析
2022/03/03 Python
俄罗斯十大城市人口排名,第三首都仅排第六,第二是北方首都
2022/03/20 杂记