前端表格自适应列宽算法不能使表格扩充到容器大小该怎么办?
我希望可以根据表头字段长度和数据的长度来计算出每一列的宽度,但是计算出来的宽度使得表格的整体宽度小于容器的大小(当计算出来的宽度大于容器大小的时候,此时出现一个滚动条,显示是合适的,没有问题的),这该怎么办?
数据:
fields
const fields = [
{
"label": "序号",
"prop": "xh",
},
{
"label": "姓名",
"prop": "xm",
},
{
"prop": "xx",
"label": "管理考核",
"children": [
{
"prop": "jl",
"label": "奖",
},
{
"prop": "kf",
"label": "罚",
},
{
"prop": "hj",
"label": "合计",
}
],
},
{
"prop": "ydjj",
"label": "应得奖金",
},
{
"prop": "sdjj",
"label": "实得奖金",
}
]
tableData
const tableData = [
{
"xh": 1,
"xm": "屈敏",
"jl": "11",
"kf": "12",
"hj": "6",
"ydjj": "",
"sdjj": ""
}]
实现思路:
export function calColsWidth(fields, tableData) {
const fontSz = 12;
const benchmarkRate = (fontSz && fontSz / 12) || 1
// 空字符长度
const nullstr = 10 * benchmarkRate + 2
// 单个中文字符长度
const chinese = 2 * benchmarkRate
// 单个非中文字符长度
const nChinese = benchmarkRate
function width(val) {
if (!val) {
return nullstr * 10
} else {
const strArr = val.toString().split("")
const pattern = new RegExp("[\u4E00-\u9FA5]+")
let re = strArr.map((str) => {
// 是否为中文
if (pattern.test(str)) {
return chinese
} else {
return nChinese
}
})
re = re.reduce((total, r) => total + r, 0)
return (re + 2) * 10
}
}
// 根据表头计算宽度
function calColsWidthByHeader(fds) {
let tot = 0;
for(const e of fds) {
const w = width(e.label);
if(!e.children) {
e.width = w;
}else {
const tw = calColsWidthByHeader(e.children);
e.width = Math.max(w, tw);
}
tot += e.width;
}
return tot;
}
function findNode(prop, fds) {
let res = null;
for(const e of fds) {
if(e.prop === prop) {
res = e;
break;
}else if(e.children) {
res = findNode(prop, e.children)
if(res) break;
}
}
return res;
}
// 根据表格数据设置宽度
function calColsWidthByTableData() {
const mp = new Map()
for(const row of tableData) {
for(const e in row) {
if(row.hasOwnProperty(e)) {
let fd = null;
if(mp.has(e)) {
fd = mp.get(e);
} else {
fd = findNode(e, fields);
mp.set(e, fd);
}
if(fd) {
const w = width(row[e])
console.log(row[e], width(row[e]))
fd.width = Math.max(fd.width, w)
}
}
}
}
// 叶子节点上的宽度更新了,但是非叶子节点上的宽度没有更新
function update(fds) {
let tot = 0;
for(const e of fds) {
if(e.children) {
e.width = update(e.children)
}
tot += e.width
}
return tot;
}
update(fields)
}
// 根据表头设置宽度
calColsWidthByHeader(fields)
console.log("calColsWidthByHeader: ", JSON.parse(JSON.stringify(fields)));
// 根据表格数据设置宽度
calColsWidthByTableData()
console.log("calColsWidthByTableData: ", JSON.parse(JSON.stringify(fields)));
return fields;
}
计算得到的新fileds,每个字段增加了新的width属性
[
{
"label": "序号",
"prop": "xh",
"width": 60
},
{
"label": "姓名",
"prop": "xm",
"width": 60
},
{
"prop": "xx",
"label": "管理考核",
"children": [
{
"prop": "jl",
"label": "奖",
"width": 40
},
{
"prop": "kf",
"label": "罚",
"width": 40
},
{
"prop": "hj",
"label": "合计",
"width": 60
}
],
"width": 140
},
{
"prop": "ydjj",
"label": "应得奖金",
"width": 120
},
{
"prop": "sdjj",
"label": "实得奖金",
"width": 120
}
]
除了不能占据整个容器之外,这里的width的计算可能也需要改进一下,因为表格数据中的数字11被换行了。
const fontSz = 12;
const benchmarkRate = (fontSz && fontSz / 12) || 1
// 空字符长度
const nullstr = 10 * benchmarkRate + 2
// 单个中文字符长度
const chinese = 2 * benchmarkRate
// 单个非中文字符长度
const nChinese = benchmarkRate
function width(val) {
if (!val) {
return nullstr * 10
} else {
const strArr = val.toString().split("")
const pattern = new RegExp("[\u4E00-\u9FA5]+")
let re = strArr.map((str) => {
// 是否为中文
if (pattern.test(str)) {
return chinese
} else {
return nChinese
}
})
re = re.reduce((total, r) => total + r, 0)
return (re + 2) * 10
}
}
针对你的问题,即前端表格自适应列宽算法不能使表格完全扩展到容器大小,同时确保表格内容不被截断或换行,你可以考虑以下解决方案:
首先,你的宽度计算算法假设了每个字符(包括数字和中文)占用的像素宽度是固定的,这在实践中可能不准确,因为不同字体和不同浏览器对字符渲染的宽度可能会有所不同。因此,一个更精确的方法是根据实际渲染的文本计算宽度。
然而,如果你坚持使用这种基于字符的算法,你可以考虑添加一个“填充宽度”来确保表格总宽度能够扩展到容器宽度。
在计算出所有列的宽度总和后,你可以计算容器宽度与列宽总和之间的差值,并将这个差值平均分配到每列上(或者根据列的优先级、内容长度等条件进行更复杂的分配)。
function distributeExtraWidth(fields, containerWidth, totalWidth) {
const extraWidth = containerWidth - totalWidth;
if (extraWidth > 0) {
// 分配额外的宽度
const columnsCount = fields.reduce((count, field) => count + (field.children ? field.children.length : 1), 0);
const perColumnWidth = extraWidth / columnsCount;
function updateFieldWidth(fields) {
for (const field of fields) {
if (field.width) {
field.width += perColumnWidth;
}
if (field.children) {
updateFieldWidth(field.children);
}
}
}
updateFieldWidth(fields);
}
}
// 在你的函数中调用它
// ...
const totalWidth = calColsWidthByHeader(fields);
const containerWidth = document.getElementById('your-table-container').offsetWidth; // 假设你的容器有一个ID
distributeExtraWidth(fields, containerWidth, totalWidth);
// ...
另一个解决方案是避免在JavaScript中计算宽度,而是使用CSS的Flexbox或Grid布局来自动处理列宽。你可以设置表格的容器为Flexbox或Grid容器,并设置表格列(或单元格)为Flex项目或Grid项,然后利用CSS的flex-grow
或grid-template-columns: repeat(auto-fill, minmax(minWidth, 1fr))
等属性来实现自动宽度分配。
如果表格的某些列包含非常长的文本,并且你希望保持列宽不变以避免表格过宽,你可能需要允许内容换行。这可以通过CSS的white-space: normal;
或word-wrap: break-word;
属性来实现。
最后,不要忘记在不同的浏览器和设备上测试你的表格,以确保它们都能正确显示。使用浏览器的开发者工具来检查元素的样式和布局,可以帮助你找到可能的问题并进行调试。
本文向大家介绍EasyUI 数据表格datagrid列自适应内容宽度的实现,包括了EasyUI 数据表格datagrid列自适应内容宽度的实现的使用技巧和注意事项,需要的朋友参考一下 项目初期在加载数据表格的时候为了提高表格数据渲染速度,设置了默认宽度。 现需求需要加一个表格自适应的功能,触发改功能,改变列宽度,但是不重新渲染表格,不发生数据请求。 设计思路,遍历每项的所有数据,比较字节符串长度,
本文向大家介绍layui表格 列自动适应大小失效的解决方法,包括了layui表格 列自动适应大小失效的解决方法的使用技巧和注意事项,需要的朋友参考一下 如下所示: 从官网复制的表格,修改成自适应宽度后失效,原因如下: 以上这篇layui表格 列自动适应大小失效的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。
本文向大家介绍使用Element UI表格如何设置列宽的宽度自适应?相关面试题,主要包含被问及使用Element UI表格如何设置列宽的宽度自适应?时的应答技巧和注意事项,需要的朋友参考一下 https://kuaizi-co.github.io/kz-table/ 列宽自适应
问题内容: 有没有一种使用HTML / CSS(具有相对大小)的方法来使一行单元格拉伸包含它的表的整个宽度? 单元格的宽度应相等,并且外部表格的大小也应使用来动态变化。 目前,如果我没有指定固定大小,单元格会自动调整大小以适合其内容。 问题答案: 您甚至不必为单元格设置特定的宽度,足以均匀地分布单元格。 请注意,要使用表格样式的元素,必须设置宽度(在我的示例中为100%)。
在使用VTable表格库做报表数据展示时,如果列的总数不足以撑开整个容器的宽度,我想能自动拉宽来适应容器大小,但当列的数量较多总宽度大于容器宽度时,又可以正常出滚动条来横向滚动。这个效果怎么实现呢?
试了很多方法,只能自适应浏览器大小,不能自适应盒子大小,想问下各位大佬有什么方法可以实现我想要的效果?