jQuery EasyUI Datagrid组件fixRowHeight接口源码分析

在庞大的Datagrid组件中,有个不起眼的接口:fixRowHeight,这个接口是不是真的是像看起来的那样不起眼呢?就其对外的用途来讲可能是不起眼,因为很少情况会用到这个接口。

然而这个对外接口调用的内部方法确实相当相当重要的,可以说没有它就没有Datagrid华丽的外衣,我将这个内部方法翻译为setRowHeight。通过对源码的分析,我们很容易知道,这个内部方法担负着同步“frozenColumns”和“普通columns”高度等重要功能,话不多说,请直接看源码:
对外接口定义
fixRowHeight: function(jq, param) {
return jq.each(function() {
setRowHeight(this, param);
});
}
setRowHeight方法
/**

  • 内部接口,设置行高
  • @param {DOM object} target datagrid宿主table对应的DOM对象
  • @param {number} rowIndex 行索引
  • @param {boolean} editing 是否在编辑状态(妈的,想了好阵子才想起这个鸟参数是用于可编辑表格,于是翻译为editing)
    */

function setRowHeight(target, rowIndex, editing) {
//一行毫无用处的代码
var rows = $.data(target, “datagrid”).data.rows;
var opts = $.data(target, “datagrid”).options;
var dc = $.data(target, “datagrid”).dc;
/**
* 需要同步"冻结列视图view1"和"普通列视图view2"两个table行高的情况,
* 为什么要同步呢?因为两个视图包含了两个不同的表格,不同表格间行跟行之间当然无法自动等高了,
* 又有哪些情况需要同步两个视图包含的两个table的行高呢?目前为止,有以下三种情况需要同步:
* 1.冻结列视图view1不为空(显示行号或者存在frozenColumns的时候),且nowrap属性为false,即文字自动换行;
* 2.冻结列视图view1不为空(显示行号或者存在frozenColumns的时候),且autoRowHeight属性为true,即行号取决于内容;
* 3.冻结列视图view1不为空(显示行号或者存在frozenColumns的时候),且有row处于可编辑状态;
/
if(!dc.body1.is(“:empty”) && (!opts.nowrap || opts.autoRowHeight || editing)) {
//如果入参存在行索引
if(rowIndex != undefined) {
//获取冻结列视图view1对应的tr
var tr1 = opts.finder.getTr(target, rowIndex, “body”, 1);
//获取普通列视图view2对应的tr
var tr2 = opts.finder.getTr(target, rowIndex, “body”, 2);
//取tr1和tr2高度的最大值,并且将tr1和tr2的高度都设置为这个最大值。
setTrHeight(tr1, tr2);
}
//如果没有行索引入参,则同步所有数据行高度。
else {
//获取所有冻结列视图数据行
var tr1 = opts.finder.getTr(target, 0, “allbody”, 1);
//获取所有普通列视图数据行
var tr2 = opts.finder.getTr(target, 0, “allbody”, 2);
//设置等高值
setTrHeight(tr1, tr2);
//如果存在footer的话,footer部分的tr(不在数据行范围内)也要同步行高
if(opts.showFooter) {
//获取所有冻结列视图footer行
var tr1 = opts.finder.getTr(target, 0, “allfooter”, 1);
//获取所有普通列视图footer行
var tr2 = opts.finder.getTr(target, 0, “allfooter”, 2);
//设置等高值
setTrHeight(tr1, tr2);
}
}
}
resizePanel(target);
//如果datagrid的height属性为auto,则根据实际数据行高度计算datagrid高度
if(opts.height == “auto”) {
var body1 = dc.body1.parent();
var body2 = dc.body2;
var height = 0;
var width = 0;
body2.children().each(function() {
var c = $(this);
if(c.is(“:visible”)) {
height += c._outerHeight();
if(width < c._outerWidth()) {
width = c._outerWidth();
}
}
});
if(width > body2.width()) {
height += 18;
}
body1.height(height);
body2.height(height);
dc.view.height(dc.view2.height());
}
dc.body2.triggerHandler(“scroll”);
/
*
* 取tr1和tr2高度的最大值,并且将tr1和tr2的高度都设置为这个最大值。
* @param {DOM object array} domtr1 tr1,注意了是个数组
* @param {DOM object array} domtr2 tr2,也是个数组
*/

function setTrHeight(domtr1, domtr2) {   
    for(var i = 0; i < domtr2.length; i++) {   
        var tr1 = $(domtr1[i]);   
        var tr2 = $(domtr2[i]);   
        tr1.css("height", "");   
        tr2.css("height", "");   
        var maxHeight = Math.max(tr1.height(), tr2.height());   
        tr1.css("height", maxHeight);   
        tr2.css("height", maxHeight);   
    }   
};   

};
resizePanel方法
setRowHeight方法用到了resizePanel,resizePanel这个方法也是一个内部的方法,并为对外提供,Datagrid内部多处使用了这个方法,我将其翻译为resizePanel应该较为贴切了,这个方法肩负着布局panel的作用,来看源码:

/**

  • 重新洗牌,计算datagrid容器布局
  • @param {DOM object} target datagrid宿主table对应的DOM对象
  • @return {undefined} 未返回结果
    */

function resizePanel(target) {
var opts = $.data(target, “datagrid”).options;
var dc = $.data(target, “datagrid”).dc;
var panel = . d a t a ( t a r g e t , " d a t a g r i d " ) . p a n e l ; v a r p a n e l W i d t h = p a n e l . w i d t h ( ) ; v a r p a n e l H e i g h t = p a n e l . h e i g h t ( ) ; v a r v i e w = d c . v i e w ; v a r v i e w 1 = d c . v i e w 1 ; v a r v i e w 2 = d c . v i e w 2 ; v a r v i e w 1 H e a d e r = v i e w 1. c h i l d r e n ( " d i v . d a t a g r i d − h e a d e r " ) ; v a r v i e w 2 H e a d e r = v i e w 2. c h i l d r e n ( " d i v . d a t a g r i d − h e a d e r " ) ; v a r v i e w 1 H e a d e r T a b l e = v i e w 1 H e a d e r . f i n d ( " t a b l e " ) ; v a r v i e w 2 H e a d e r T a b l e = v i e w 2 H e a d e r . f i n d ( " t a b l e " ) ; v i e w . w i d t h ( p a n e l W i d t h ) ; / / 这个地方可以使用 .data(target, "datagrid").panel; var panelWidth = panel.width(); var panelHeight = panel.height(); var view = dc.view; var view1 = dc.view1; var view2 = dc.view2; var view1Header = view1.children("div.datagrid-header"); var view2Header = view2.children("div.datagrid-header"); var view1HeaderTable = view1Header.find("table"); var view2HeaderTable = view2Header.find("table"); view.width(panelWidth); //这个地方可以使用 .data(target,"datagrid").panel;varpanelWidth=panel.width();varpanelHeight=panel.height();varview=dc.view;varview1=dc.view1;varview2=dc.view2;varview1Header=view1.children("div.datagridheader");varview2Header=view2.children("div.datagridheader");varview1HeaderTable=view1Header.find("table");varview2HeaderTable=view2Header.find("table");view.width(panelWidth);//这个地方可以使用.data(target,‘datagrid’).dc.header1直接获取到,为何还要用jquery去检索DOM是个疑问。
//div.datagrid-header-inner在easyui.css中的宽度是定义为10000的。
var header1 = view1Header.children(“div.datagrid-header-inner”).show();
//根据标题的表格宽度设置view1宽度
//你妈的,header1.find(“table”)不就是前面的view1HeaderTable么,这里又用jquery检索,真特么的没事找事干。
view1.width(header1.find(“table”).width());
if(!opts.showHeader) {
header1.hide();
}
//view2的宽度设置为panel去除view1的宽度
view2.width(panelWidth - view1._outerWidth());
//统一header body footer的宽度
view1.children(“div.datagrid-header,div.datagrid-body,div.datagrid-footer”).width(view1.width());
view2.children(“div.datagrid-header,div.datagrid-body,div.datagrid-footer”).width(view2.width());
var hh;
view1Header.css(“height”, “”);
view2Header.css(“height”, “”);
view1HeaderTable.css(“height”, “”);
view2HeaderTable.css(“height”, “”);
//获取两个视图表格较大的高度值,以此值设置两表格同步高度
hh = Math.max(view1HeaderTable.height(), view2HeaderTable.height());
view1HeaderTable.height(hh);
view2HeaderTable.height(hh);
view1Header.add(view2Header)._outerHeight(hh);
//如果高度不是auto的话,则处理frozenRows
if(opts.height != “auto”) {
var bodyHeight = panelHeight - view2.children(“div.datagrid-header”)._outerHeight() - view2.children(“div.datagrid-footer”)._outerHeight() - panel.children(“div.datagrid-toolbar”)._outerHeight();
panel.children(“div.datagrid-pager”).each(function() {
bodyHeight -= $(this)._outerHeight();
});
//设置frozenRows所在表格为绝对定位脱离普通文档流,它像一只断了线的气球,嗖的一下就想往云彩里飘
//可惜啊,它被天花板挡住了,只能跟吊死鬼一样,挂在天花板下,这个天花板就是dc.view1以及dc.view2了,因为dc.view1以及dc.view2也是绝对定位。
//既然dc.view1以及dc.view2也是绝对定位,他们肯定也想往云彩里钻(可能是云彩里棉花糖多),不过总有一块更高的天花板会挡住他们的去路。
//top属性的设置,决定了frozenRows会悬浮在离天花板dc.header2._outerHeight()距离处。
dc.body1.add(dc.body2).children(“table.datagrid-btable-frozen”).css({
position: “absolute”,
top: dc.header2._outerHeight()
});
//获得frozenRows的高度
var frozenRowsHeight = dc.body2.children(“table.datagrid-btable-frozen”)._outerHeight();
//为啥要设置marginTop呢,因为有个吊死鬼吊在半空,没有margin的话,非frozenRows的内容就得被吊死鬼挡住一部分
//当然了,高度得把frozenRowsHeight去掉,否则有了marginTop,高度又不减少,会把两个view撑出额外的高度
view1.add(view2).children(“div.datagrid-body”).css({
marginTop: frozenRowsHeight,
height: (bodyHeight - frozenRowsHeight)
});
//到这里,我们应该理解一个问题了,为何满足opts.height != "auto"条件,才会进行这段运算
//如果高度为auto的话,他娘的肯本不会有垂直滚动条,那么你冻结的rows还有什么个鸟意义呢
}
view.height(view2.height());
};
http://www.easyui.info/archives/1168.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值