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 相关文章推荐
JavaScript中几种常见排序算法小结
Feb 22 Javascript
javascript动态加载实现方法一
Aug 22 Javascript
js+css实现的圆角边框TAB选项卡滑动门代码分享(2款)
Aug 26 Javascript
JS实现的3D拖拽翻页效果代码
Oct 31 Javascript
AngularJS初始化静态模板详解
Jan 14 Javascript
微信小程序 在Chrome浏览器上运行以及WebStorm的使用
Sep 27 Javascript
JS判断两个对象内容是否相等的方法示例
Apr 10 Javascript
JavaScript创建对象的七种方式全面总结
Aug 21 Javascript
p5.js入门教程之图片加载
Mar 20 Javascript
关于AOP在JS中的实现与应用详解
May 06 Javascript
解决layer.prompt无效的问题
Sep 24 Javascript
Vue OpenLayer 为地图绘制风场效果
Apr 24 Vue.js
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入门学习知识点三 PHP上传
2011/07/14 PHP
PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享
2014/09/27 PHP
织梦sitemap地图实时推送给百度的教程
2015/08/03 PHP
PHP模块化安装教程
2016/06/01 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
JAVASCRIPT实现的WEB页面跳转以及页面间传值方法
2010/05/13 Javascript
各浏览器对click方法的支持差异小结
2011/07/31 Javascript
js显示文本框提示文字的方法
2015/05/07 Javascript
js实现仿网易点击弹出提示同时背景变暗效果
2015/08/13 Javascript
JavaScript中的继承之类继承
2016/05/01 Javascript
Angularjs使用ng-repeat中$even和$odd属性的注意事项
2016/12/31 Javascript
JavaScript 详解预编译原理
2017/01/22 Javascript
webpack之devtool详解
2018/02/10 Javascript
vue路由结构可设一层方便动态添加路由操作
2020/08/31 Javascript
使用vue构建多页面应用的示例
2020/10/22 Javascript
vant中的toast层级改变操作
2020/11/04 Javascript
python文件与目录操作实例详解
2016/02/22 Python
Python使用redis pool的一种单例实现方式
2016/04/16 Python
python和shell监控linux服务器的详细代码
2018/06/22 Python
python3 kmp 字符串匹配的方法
2018/07/07 Python
python的turtle库使用详解
2019/05/10 Python
Python环境下安装PyGame和PyOpenGL的方法
2020/03/25 Python
浅谈Python 参数与变量
2020/06/20 Python
使用CSS媒体查询(Media Queries)和JavaScript判断浏览器设备类型的方法
2014/04/03 HTML / CSS
欧洲最大的化妆品连锁公司:Douglas道格拉斯
2017/05/06 全球购物
女士和男士时尚鞋在线购物:Shoespie
2019/02/28 全球购物
英国现代市场:ARKET
2019/04/10 全球购物
俄罗斯在线服装店:STOLNIK
2021/03/07 全球购物
Python文件操作的面试题
2013/06/22 面试题
毕业生的自我评价分享
2013/12/18 职场文书
运动会演讲稿100字
2014/08/25 职场文书
老干部局2015年度工作总结
2015/10/22 职场文书
幼儿园体操比赛口号
2015/12/25 职场文书
JUnit5常用注解的使用
2021/07/02 Java/Android
学习nginx基础知识
2021/09/04 Servers
图神经网络GNN算法
2022/05/11 Python