视频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
EasyUI 数据表格datagrid列自适应内容宽度的实现
2020-11-27 21:53:38 责编:小采
文档

项目初期在加载数据表格的时候为了提高表格数据渲染速度,设置了默认宽度。

现需求需要加一个表格自适应的功能,触发改功能,改变列宽度,但是不重新渲染表格,不发生数据请求。

设计思路,遍历每项的所有数据,比较字节符串长度,取最大长度。再用最大长度和标题长度比较,如果标题长就去标题长度,如果字符串长,就取字符串的。

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('');//清空表格自适应时计算的表头宽度
 }
 },

下载本文
显示全文
专题