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(一)jquery选择符 必备知识点
Nov 25 Javascript
js控制的回到页面顶端goTop的代码实现
Mar 20 Javascript
使用jquery中height()方法获取各种高度大全
Apr 02 Javascript
JavaScript异步编程Promise模式的6个特性
Apr 03 Javascript
jquery ztree实现下拉树形框使用到了json数据
May 14 Javascript
vue.js父组件使用外部对象的方法示例
Apr 25 Javascript
解决vue的变量在settimeout内部效果失效的问题
Aug 30 Javascript
在angularJs中进行数据遍历的2种方法
Oct 08 Javascript
ES6 fetch函数与后台交互实现
Nov 14 Javascript
vue路由中前进后退的一些事儿
May 18 Javascript
Vue实现数据请求拦截
Oct 23 Javascript
解决vue-router路由拦截造成死循环问题
Aug 05 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.MVC的模板标签系统(二)
2006/09/05 PHP
PHP统计目录下的文件总数及代码行数(去除注释及空行)
2011/01/17 PHP
Php中使用Select 查询语句的实例
2014/02/19 PHP
使用php清除bom示例
2014/03/03 PHP
php基于socket实现SMTP发送邮件的方法
2015/03/05 PHP
php单元测试phpunit入门实例教程
2017/11/17 PHP
javascript对象的property和prototype是这样一种关系
2007/03/24 Javascript
JsDom 编程小结
2011/08/09 Javascript
JS获取并操作iframe中元素的方法
2013/03/21 Javascript
javascript几个易错点记录
2014/11/26 Javascript
快速掌握Node.js之Window下配置NodeJs环境
2016/03/21 NodeJs
jQuery学习笔记之入门
2016/12/14 Javascript
微信小程序 网络请求(post请求,get请求)
2017/01/17 Javascript
在点击div中的p时,如何阻止事件冒泡
2017/02/07 Javascript
JavaScript实现鼠标点击导航栏变色特效
2017/02/08 Javascript
BootStrap 导航条实例代码
2017/05/18 Javascript
基于Cookie常用操作以及属性介绍
2017/09/07 Javascript
基于jQuery Ajax实现下拉框无刷新联动
2017/12/06 jQuery
详解vuex持久化插件解决浏览器刷新数据消失问题
2019/04/15 Javascript
详解vue-cli+es6引入es5写的js(两种方法)
2019/04/19 Javascript
微信小程序-form表单提交代码实例
2019/04/29 Javascript
详解微信小程序网络请求接口封装实例
2019/05/02 Javascript
[02:29]DOTA2英雄基础教程 陈
2013/12/17 DOTA
[01:32]TI珍贵瞬间系列(一)
2020/08/26 DOTA
python3结合openpyxl库实现excel操作的实例代码
2018/09/11 Python
浅谈python 读excel数值为浮点型的问题
2018/12/25 Python
django2.0扩展用户字段示例
2019/02/13 Python
什么是Python中的匿名函数
2020/06/02 Python
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
荷兰牛仔裤网上商店:Jeans Centre
2018/04/03 全球购物
80年代复古T恤:TruffleShuffle
2018/07/02 全球购物
外贸主管求职简历的自我评价
2013/10/23 职场文书
销售演讲稿范文
2014/01/08 职场文书
无传销社区工作方案
2014/05/13 职场文书
2015年考研复习计划
2015/01/19 职场文书
CSS实现单选折叠菜单功能
2021/11/01 HTML / CSS