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里的依赖注入
Mar 19 Javascript
JavaScript实现关键字高亮功能
Nov 12 Javascript
javascript折半查找详解
Jan 26 Javascript
jquery 插件实现瀑布流图片展示实例
Apr 03 Javascript
js实现分享到随页面滚动而滑动效果的方法
Apr 10 Javascript
jquery代码实现简单的随机图片瀑布流效果
Apr 20 Javascript
JavaScript中的getTimezoneOffset()方法使用详解
Jun 10 Javascript
基于vue实现swipe分页组件实例
May 25 Javascript
基于 Bootstrap Datetimepicker 联动
Aug 03 Javascript
基于Vue生产环境部署详解
Sep 15 Javascript
JS实现水平移动与垂直移动动画
Dec 19 Javascript
js 实现碰撞检测的示例
Oct 28 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 CURL用法的深入分析
2013/06/09 PHP
php结合js实现点击超链接执行删除确认操作
2014/10/31 PHP
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
php获取数组元素中头一个数组元素值的实现方法
2014/12/20 PHP
PHP 接入支付宝即时到账功能
2016/09/18 PHP
Yii2-GridView 中让关联字段带搜索和排序功能示例
2017/01/21 PHP
thinkPHP5框架实现基于ajax的分页功能示例
2018/06/12 PHP
PHP7新特性之抽象语法树(AST)带来的变化详解
2018/07/17 PHP
php生成微信红包数组的方法
2019/09/05 PHP
PHP解密支付宝小程序的加密数据、手机号的示例代码
2021/02/26 PHP
javascript 循环读取JSON数据的代码
2010/07/17 Javascript
用jquery统计子菜单的条数示例代码
2013/10/18 Javascript
jQuery实现友好的轮播图片特效
2015/01/12 Javascript
jQuery实现三级菜单的代码
2016/05/09 Javascript
JS如何判断json是否为空
2016/07/06 Javascript
用JS写的一个Ajax库(实例代码)
2016/08/06 Javascript
详解nodejs微信公众号开发——2.自动回复
2017/04/10 NodeJs
详解Vue 项目中的几个实用组件(ts)
2019/10/29 Javascript
深入理解 TypeScript Reflect Metadata
2019/12/12 Javascript
vue 修改 data 数据问题并实时显示操作
2020/09/07 Javascript
vue项目如何监听localStorage或sessionStorage的变化
2021/01/04 Vue.js
深入解析Python中的变量和赋值运算符
2015/10/12 Python
python将ansible配置转为json格式实例代码
2017/05/15 Python
python实时监控cpu小工具
2018/06/21 Python
详解python中自定义超时异常的几种方法
2019/07/29 Python
解决pyinstaller 打包exe文件太大,用pipenv 缩小exe的问题
2020/07/13 Python
Python二元算术运算常用方法解析
2020/09/15 Python
Python3+SQLAlchemy+Sqlite3实现ORM教程
2021/02/16 Python
基于HTML5 Canvas 实现弹出框效果
2017/06/05 HTML / CSS
采购意向书范本
2014/03/31 职场文书
党的群众路线教育实践活动个人对照检查材料范文
2014/09/25 职场文书
加班费申请报告
2015/05/15 职场文书
党员反邪教心得体会
2016/01/15 职场文书
公开致歉信
2019/06/24 职场文书
2019年XX公司的晨会制度及流程!
2019/07/23 职场文书
聊聊SpringBoot自动装配的魔力
2021/11/17 Java/Android