共计 2583 个字符,预计需要花费 7 分钟才能阅读完成。
项目初期在加载数据表格的时候为了提高表格数据渲染速度,设置了默认宽度。
现需求需要加一个表格自适应的功能,触发改功能,改变列宽度,但是不重新渲染表格,不发生数据请求。
设计思路,遍历每项的所有数据,比较字节符串长度,取最大长度。再用最大长度和标题长度比较,如果标题长就去标题长度,如果字符串长,就取字符串的。
js
// 表格自适应方法
function changeWidth(agstr){var dg = $('#'+agstr);
dg.datagrid("loading");// 显示加载状态 $$$
var fn=function(){var opts = dg.datagrid('getColumnFields'); // 获取表头所有 field
var data=dg.datagrid('getData');// 获取数据表格请求的数据
var role = data.rows;// 数据表格请求的数据, 即每行的数据
for (var i = 0; i <opts.length ;i++) { // 循环每一列的数据内容
var field=opts[i];
var ro_width = 0;
if(field != ''){var col = dg.datagrid('getColumnOption', field);
var col_title = col.title;
for(j=0;j<role.length;j++){if(StringTolog(role[j][field])>ro_width){ro_width = StringTolog(role[j][field]);// 比较当前 field 列的每条数据长度,取最大值
}
}
if(ro_width<StringTolog(col_title)){// 如果当前列数据长度小于当前列表头长度则取表头长度
ro_width =StringTolog(col_title);
}
var ro_length=ro_width*14+10;//14 是页面字体像素大小 10 是单元格左右内边距大小
$("td[field='"+field+"'] div").width(ro_length);// 设置列宽样式
dg.datagrid('lockColumn',field);// 禁止数据表格改变列宽※※※
}
}
dg.datagrid("loaded");// 隐藏加载状态 $$$
}
setTimeout(fn,0);
}
// 字符串的粗略换算
function StringTolog(Str){if(Str==null){return 0;}
Str = Str.toString();// 该方法将取到的数据转为 String 类型
Str = Str.replace(/\s+/g,'');// 替换空格
// 两个字节为长度 1,一个字节为长度 0.5,计算字符串总长度
var newStr = (Str.length-Str.replace(/[\x00-\xff]+/g,'').length)/2
+Str.replace(/[\x00-\xff]+/g,'').length;
return newStr;
}
调用以上两个方法就可以实现列宽自适应。
但是发现执行此方法之后,表头和表身的单元格宽度都已经固定写死,如果此时触发调整列宽大小事件,只能改变表头宽度,不会改变表身列宽,所以自适应列宽后可以取消改变列宽大小的功能
封装冻结列方法:
// 冻结列,禁止调节列尺寸 $("#id").datagrid('lockColumn',field 值);
$.extend($.fn.datagrid.methods, {lockColumn: function(jq, field){return jq.each(function(){var p = $(this).datagrid('getPanel'); // 获取数据表格面板
var cell = p.find('div.datagrid-header td[field=' + field + '] > div.datagrid-cell'); // 获取数据表格监听改变列宽事件的节点
cell.resizable({disabled:true}); // 禁止改变列宽
});
}
});
在给每列设置宽度的时候调用该方法
dg.datagrid(‘lockColumn’,field);
changeWidth 方法中的※※※位置
在重新定义列宽的时候如果数据量过大会导致页面卡顿,可以再触发该方法的开始位置调用 datagrid 的 loading 方法,结束时调用 loaded 方法,changeWidth 方法中的 $$$ 位置
因为在触发表格自适应方法后调用了 datagrid 的冻结列方法,所以再重新查询数据的时候表头不会重新渲染,只有表身会,,表身就会恢复默认宽度,就会出现表头和表身对不齐的问题,表头也不能改变宽度。
解决办法,在数据表格数据加载成功时取消冻结列,清空之前计算的列宽
封装取消冻结列方法
// 取消冻结列,允许调节列尺寸 $("#id").datagrid('unlockColumn',field 值);
$.extend($.fn.datagrid.methods, {unlockColumn: function(jq, field){return jq.each(function(){var p = $(this).datagrid('getPanel'); // 获取数据表格面板
var cell = p.find('div.datagrid-header td[field=' + field + '] > div.datagrid-cell'); // 获取数据表格监听改变列宽事件的节点
cell.resizable({disabled:false}); // 允许改变列宽
});
}
});
数据加载成功触发
onLoadSuccess: function (data) {var opts = $(this).datagrid('getColumnFields'); // 获取表头所有 field
for(var i=0;i<opts.length;i++){$(this).datagrid('unlockColumn',opts[i]);// 允许调整列尺寸
$("tr.datagrid-header-row td[field='"+opts[i]+"'] div").width('');// 清空表格自适应时计算的表头宽度
}
},
正文完
发表至: javascript
2019-07-18