实现table表格指定单元格自适应宽度

分享 未结 5 1917
敲键盘的猿
悬赏:20飞吻
目前,table组件暂时无法实现指定字段的单元格宽度自适应内容宽度,只能设置所有列平均分配表格的宽度(配置对象表头参数cols中,所有字段不设置width属性),这种情况如下图所示:



那么,现在有个需求,某些重要的列我希望它的宽度适应单元格内容的宽度,这样我就不需要每次查看这列数据时都手动调整列宽了(因为这列数据的宽度不固定,所以无法设置固定的列宽,如上图的“单号”列)

而如果单独把指定列设置为{width: "auto"},就会出现下图的情况:



可见,上面的表头错位了(这应该是个bug)[汗]

查看table组件的html结构可知,table表格实际是由两个<table>标签组成的,出现表头错位的原因应该是表头对应的单元格宽度没有设置好。

那么我的解决思路是这样的:

既然把相应的列宽度设为auto,表体相应的列已经宽度自适应了,只是表头错位了而已,那就手动设置一下表头的宽度就可以了。

审查table组件相应html元素,以及查看table.js源码,可知单元格的宽度是由“'.laytable-cell-'+ key”这个类样式设置的,通过js动态生成style元素,添加相应样式后插入html中,表格渲染完成后需要手动调整表格列宽度,再通过这个style元素修改相应列的宽度:


好了,那么修复这个小bug的核心代码如下:
/**
* layui table表格指定单元格自适应宽度
* 注意:需要在表格配置参数中设置相应字段{width: "auto"}
* 推荐在table的done事件中调用
* @param {jQueryObject} $curTableDom 所在表格table元素的jQuery对象
* @param {Array} fieldArr 需要宽度自适应的字段数组
*/
function setAutoColWidth($curTableDom, fieldArr){
let styleDom = $curTableDom.next().find('style')[0]; //获取相应表格html中style元素的DOM对象
let sheet = styleDom.sheet || styleDom.styleSheet || {};
let rules = sheet.cssRules || sheet.rules; //获取css样式规则类数组对象
let relesLength = rules.length;

let $targetTd = ''; //字段所在td元素的jq对象
let key = ''; //字段的key
let colWidth = ''; //已经宽度自适应的div宽度

fieldArr.forEach( (item, index) => {
$targetTd = $curTableDom.next().find(`td[data-field=${ item }]`);
key = $targetTd.data('key');
colWidth = $targetTd.find('div').css('width');
for(let i = 0; i < relesLength; i ++){
if(rules[i].selectorText === ('.laytable-cell-'+ key)){ //对应字段的css样式规则
rules[i].style.width = colWidth; //设置对应字段的单元格宽度
break;
}
}
});
}
在table渲染方法的done回调中调用这个方法即可:
layui.table.render({
elem: '#demo',
cellMinWidth: 100,
height: 200,
width: 750,
cols: [[
{ field: 'TradeKey', title: '单号', align: 'center', width: "auto" },
{ field: 'User', title: '操作人', align: 'center' },
{ field: 'Event', title: '事件', align: 'center' },
{ field: 'EventDetail', title: '事件详情', align: 'center' },
{ field: 'ExcuteTime', title: '操作时间', align: 'center', width: "auto" },
]],
done: function(){
//设置指定单元格宽度自适应
//this.elem就是上面elem属性所指的dom元素的jq对象
//设置延时是因为有时表格数据过多,还没渲染完成这时获取的列宽度是0px,这时调用这个方法是无法设置成功的
//这个延时的时间可以根据自己的实际情况设置
setTimeout( () => setAutoColWidth(this.elem, ["TradeKey", "ExcuteTime"]), 500 );
},
id: "demo"
});
调整后的效果如下(“单号”和“操作时间”两列的宽度已经自适应了。其实这个例子并不完全能说明问题,因为这两列的数据其实是固定宽度的,“事件详情”这一类的不确定宽度的数据就比较合适,演示用的数据就不要太纠结了哈[嘻嘻] ):


至于表格右侧的空格如果需要填满的话,就再加几行代码实现就行了,这个不难。因为我没有这个需求,我的列比较多肯定会有滚动条,所以就不做了[嘻嘻]

这就是我目前所实现的方法,如果大家有更好的方法,请多多指教![嘻嘻]
回帖
  • [good] 谢谢分享
    0 回复
  • tianshc56
    2019-7-17
    [good] ,感谢分享
    0 回复
  • Lucky615
    2019-7-25
    感谢分享[good]
    0 回复
  • miniy
    2019-10-25
    感谢分享[good]
    0 回复
  • 你好,我这边根据你的方法,是可以修复这个问题,但是呢,我的表列比较多,会出现拖动条,拖动之后,表头的内容不会随着一起移动,这个是什么原因呢?我主要做后端的,前端基础比较薄弱,还望不吝赐教。谢谢~@ 敲键盘的猿
    0 回复