视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
数据表格自动分配列宽的一种实现方法
2020-11-03 23:08:45 责编:小采
文档


layui数据表格自动分配列宽效果图:

适用场景:
主要是解决窗口大小改变后表格尾列出现空白和滚动条的问题
-窗口由小变大,出现表格尾列出现空白

窗口由大变小,出现横向滚动条

重新加载框架后恢复正常

使用前提:

-每一列的表头必须全部设置minWidth(依靠minWidth属性进行的判断)

-自己中间使用的<iframe>,其他方式效果未知

-页面只能有一个数据表格,多个数据表格的话需要自己修改代码(表格的判断,列数的获取等)

具体步骤:

-监听窗口大小改变事件

var resizeTimer;
 $(window).resize(function () {
 if (resizeTimer) {
 clearTimeout(resizeTimer);
 }
 resizeTimer = setTimeout(function () {
 resizeTimer = null;
 dstributionColumnWidth();
 }, 200);
 });
/*
经过测试发现,当窗口大小改变之后,这个方法会调用多次
所以需要使用clearTimeout方法取消由 setTimeout() 方法设置的 timeout
也就是说每一次调用后200毫秒内的下一次调用都会取消上一次的调用
这样可以大概率保证最终只执行一次
如果还是不行就把200调大点比如500
当然值越小,给人的感觉越流畅
*/

获取表格的宽度、列数、求出平均列宽

// 表格宽度
var tabWidth = $(".layui-table-header").width();
// 列数
var colNum = $("tr").eq(0).find("th").length;
// 平均列宽
var avgWidth = tabWidth / colNum;
/*
求宽度和列宽的方式比较简单,也不知道有没有通用性(水平所限),
自己使用没有问题,如果大家拿不到值的话就根据自己的情况写代码拿到相应的值就行了,
当然要是有更好更优雅的方法也一定要留言告诉我
*/

获取每一列的data-field和data-minwidth属性的值并封装为对象,并按照data-minwidth的值由大到小排序

/**
 * 列对象
 * @param index 所在列在当前行中的索引位置(没用上可以不要)
 * @param name 对应表头中设置的field
 * @param minWidth 对象表头中的minWidth
 * @param width 最终的宽度
 * @constructor
 */
 function Column(index, name, minWidth, width) {
 this.index = index;
 this.name = name;
 this.minWidth = minWidth;
 this.width = width;
 }

// 获取参数封装对象
if (cols === undefined) {
 cols = $("tr").eq(0).find("th").map(function (index, item) {
 var col = new Column(index, $(this).attr("data-field"), $(this).attr("data-minwidth"));
 return col;
 });
 // 排序
 cols.sort(function (a, b) {
 return b["minWidth"] - a["minWidth"];
 });
 }

/**
 * 计算列宽
 * @param columns column对象数组
 * @param colNum 列数
 * @param tabWidth 表格宽度
 * @param avgWidth 平均宽度
 */
 function calculateColumnWidth(columns, colNum, tabWidth, avgWidth) {
 // 是否显示表格横向滚动条
 showOverflowX = false;
 // 是否完成比较
 var isComplete = false;
 for (var i = 0; i < columns.length; i++) {
 var column = columns[i];
 // 如果计算出的平均列宽比最大的minWidth还要大,那么剩下的就不用比较了,直接赋值即可
 if (column["minWidth"] <= avgWidth || isComplete) {
 column["width"] = parseInt(avgWidth);
 isComplete = true;
 } else {
 /* 
 如果minWidth > 平均列宽,那么就用表格宽度减去minWidth 
 然后除以列数-1,重新求平均列宽
 */
 column["width"] = column["minWidth"];
 tabWidth -= column["minWidth"];
 colNum -= 1;
 avgWidth = tabWidth / colNum;
 // 如果最后一列时,平均列宽大于最小列宽,说明当前页面的宽度足够显示表格,就可以隐藏横向滚动条,反之则需要显示滚动条
 if (i == columns.length - 1) {
 showOverflowX = true;
 }
 }
 }
 }

设置单元格宽度、设置滚动条

// 这里是根据名称查找相应的th、td标签,可能有更好的方法,欢迎留言
for (var i = 0; i < cols.length; i++) {
 var col = cols[i];
 var width = cols[i].width;
 $("[data-field='" + cols[i]["name"] + "']").each(function () {
 // 实际修改的是th、td下的div标签
 // 我使用的是动画的方式,也可以选择直接赋值
 $(this).children().eq(0).animate({width: width}, 200);
 })
 }

// 根据showOverflowX的值判断是否需要显示滚动条
if (showOverflowX) {
 $('.layui-table-body').css({"overflow-x": "auto"});
} else {
 $('.layui-table-body').css({"overflow-x": "hidden"});
}

完成!
完整代码

var cols, showOverflowX;

 /**
 * 列对象
 * @param index 所在列在当前行中的索引位置(没用上可以不要)
 * @param name 对应表头中设置的field
 * @param minWidth 对象表头中的minWidth
 * @param width 最终的宽度
 * @constructor
 */
 function Column(index, name, minWidth, width) {
 this.index = index;
 this.name = name;
 this.minWidth = minWidth;
 this.width = width;
 }

 /**
 * 计算列宽
 * @param columns column对象数组
 * @param colNum 列数
 * @param tabWidth 表格宽度
 * @param avgWidth 平均宽度
 */
 function calculateColumnWidth(columns, colNum, tabWidth, avgWidth) {
 showOverflowX = false;
 var isComplete = false;
 for (var i = 0; i < columns.length; i++) {
 var column = columns[i];
 if (column["minWidth"] <= avgWidth || isComplete) {
 column["width"] = parseInt(avgWidth);
 isComplete = true;
 } else {
 column["width"] = column["minWidth"];
 tabWidth -= column["minWidth"];
 colNum -= 1;
 avgWidth = tabWidth / colNum;
 if (i == columns.length - 1) {
 showOverflowX = true;
 }
 }
 }
 }

 /**
 * 分配列宽
 */
 function dstributionColumnWidth() {
 // 表格宽度
 var tabWidth = $(".layui-table-header").width();
 // 列数
 var colNum = $("tr").eq(0).find("th").length;
 // 平均列宽
 var avgWidth = tabWidth / colNum;

 if (cols === undefined) {
 cols = $("tr").eq(0).find("th").map(function (index, item) {
 var col = new Column(index, $(this).attr("data-field"), $(this).attr("data-minwidth"));
 return col;
 });
 cols.sort(function (a, b) {
 return b["minWidth"] - a["minWidth"];
 });
 }

 calculateColumnWidth(cols, colNum, tabWidth, avgWidth);

 for (var i = 0; i < cols.length; i++) {
 var col = cols[i];
 var width = cols[i].width;
 $("[data-field='" + cols[i]["name"] + "']").each(function () {
 $(this).children().eq(0).animate({width: width}, 200);
 })
 }

 if (showOverflowX) {
 $('.layui-table-body').css({"overflow-x": "auto"});
 } else {
 $('.layui-table-body').css({"overflow-x": "hidden"});
 }
 }

 var resizeTimer;
 $(window).resize(function () {
 if (resizeTimer) {
 clearTimeout(resizeTimer);
 }
 resizeTimer = setTimeout(function () {
 resizeTimer = null;
 dstributionColumnWidth();
 }, 200);
 });

使用方法

layui.config({
 // 放到这个目录里
 base: '/static/js/extend/'
}).extend({formSelects: 'formSelects-v4.min'});
 // 这里
layui.use(['table', 'element', 'layer', 'jquery', 'form', 'formSelects', 'tools', 'autoColumnWidth'], function () {
 var table = layui.table,
 element = layui.element,
 layer = layui.layer,
 $ = layui.$,
 form = layui.form,
 formSelects = layui.formSelects,
 tools = layui.tools,
 // 这里
 autoColumnWidth = layui.autoColumnWidth;

然后在需要的地方直接调用

autoColumnWidth.resize();

ps:窗口大小监听代码还是要自己写的

想要数据表格加载之后就分配列宽可以写在done的回调里

done: function () {
 autoColumnWidth.resize();
}

推荐:layui使用教程

下载本文
显示全文
专题