开发背景

  表格插件之前我也写个一篇,当时写那个插件的时候,我自己还没有总结出写插件的方法,虽然功能实现了,但是使用起来还是有点别扭的,并且需要在调用写添加特定名称的方法,这个地方着实违背了开发插件的易用性。所以,我今天决定重构之前的代码,按照现有的开发插件框架进行一次大修整。这也类似于软件开发过程中的代码重构阶段吧,把一些不合理的代码、思想、逻辑等及时修改掉。

  其实代码重构在软件开发过程中特别重要。开发过程中,可能会由于开发时间的限制等因素,为了及时完成任务,不得已写一些没有经过斟酌的代码,我们不能对已经写的代码置之不理,要在闲下来的事件将这些代码重构下,这样使自己的代码冗余减少,质量也提高很多。并且逻辑会更加清晰等等好处。这里就不一一说了。太乱的代码,时间久了,可能连自己都不想看了,也许也是看不懂了。很多程序猿都没有重构代码的习惯,以完成任务为目的,同时也担心修改错了等,以各种理由说服自己不去QA自己的代码。在这里,我还是那句话,作为想成为“攻城狮”的“猿们”,请对自己负责,对自己的代码负责。我不是牛人,但是我有一颗必须成为牛人的心。和我一样,奋斗在“一线”的猿们,努力吧,自勉吧。

  背景交代完毕,其实那个多也就汇成一句话,请不定时去QA自己代码。以下就是我对上次GridData代码的重构吧。当然,思想也改变了。

  记得之前写了很多自定义属性,当然这次也有,但是,就不放在代码层次的最外层了,为了代码结构的整齐,就将其放在插件开发的里面了。这次我还是重头开始说起吧。说实话,本插件的参数很多都是仿照easy ui 中的GridData。为啥要仿照呢,其实我本人是不建议使用easy ui的,虽然功能强大,但是功能太死,二次开发时间成本比较高。因为他们开发团队将很多东西都分装的太死。其实也不能怪别人。人家辛辛苦苦开发的东西,当然不想被别人那个轻易就拿走喽。理解万岁!当然也不是完全不能二次开发,你得去理解人家的规范,那样就是可以了。之前我有对其中的Tree控件、TreeGrid控件等做了二次开发。目的当然是为了适应工作需要了。^_^

  所以呢,很多大公司都会有自己的一套插件库的。这样便于维护、扩展。这个好处就不用我多说了,大家都懂的。好了,回归正题,不然又扯远了。

  哦,对了,上一篇博文中漏了公共Js代码了,不好意思。。。。这边等会我将补上。

  先说下本插件的功能吧:1、支持分页;2、支持多种皮肤选择;3、支持对列设置样式。4、其他正常的表格功能(不多说了)。

开发过程

  本次开发过程中分五个部分:

  第一部分:公共js和公共css样式部分;

  第二部分:自定义特性(如:皮肤风格选择等)部分;

  第三部分:具体定义及实现部分;

  第四部分:对外开放部分;

  第五部分:具体使用部分;

  接下来我将对开发过程中的五个部分进行具体说明。

详细开发设计

  第一部分:公共js和公共css样式开发,这里涉及克隆对象(cloneObject)、创建委托(delegate)、获取参数(getParam)、判断元素是否存在某个属性(boolHasAttr)、字符串是否为空(IsNull)等。该部分可以以后继续添加公共代码,具体代码实现如下:

 1 $(function () {
 2     /// 创建委托函数
 3     ///      context:函数上下文
 4     ///      params:参数【必须是数组形式】,可以为空
 5     Function.prototype.delegate = function (context, params) {
 6         var func = this;
 7         return function () {
 8             if (params == null) {
 9                 return func.apply(context);
10             }
11             return func.apply(context, params);
12         };
13     };
14     $.extend({
15         coverObject: function (obj1, obj2) {
16             var o = this.cloneObject(obj1, false);
17             var name;
18             for (name in obj2) {
19                 if (obj2.hasOwnProperty(name)) {
20                     o[name] = obj2[name];
21                 }
22             }
23             return o;
24         },
25         cloneObject: function (obj, deep) {
26             if (obj === null) {
27                 return null;
28             }
29             var con = new obj.constructor();
30             var name;
31             for (name in obj) {
32                 if (!deep) {
33                     con[name] = obj[name];
34                 } else {
35                     if (typeof (obj[name]) == "object") {
36                         con[name] = $.cloneObject(obj[name], deep);
37                     } else {
38                         con[name] = obj[name];
39                     }
40                 }
41             }
42             return con;
43         },
44         ///说明:
45         ///      创建委托
46         delegate: function (func, context, params) {
47             if ($.isFunction(func)) {
48                 return func.delegate(context, params);
49             } else {
50                 return $.noop;
51             }
52         },
53         getParam: function (param) {
54             if (typeof (param) == "undefined") {
55                 return "";
56             } else {
57                 return param;
58             }
59         },
60         ///说明:
61         ///      判断元素是否存在某个属性
62         boolHasAttr: function (id, attr) {
63             if (typeof ($("#" + id).attr(attr)) != "undefined") {
64                 return false;
65             }
66             return true;
67         },
68         IsNull: function (str) {
69             if ($.trim(str) == "" || isNaN(str)) {
70                 return true;
71             }
72             return false;
73         }
74     });
75 });
公共js代码
.gridData_tableFoot{
    width: auto;height:24px;margin: 0px auto;line-height: 24px;
}
.gridData_tableFoot div{
   width: auto;height :100%;margin-left: 5px;cursor: pointer;float: left
}
.tableBodyCur {
   cursor: pointer 
}
.lieStyle{
   color: #205ed7 ;
   border-color:#D4DBE1 
}
thead td,tbody td{
   border: 1px solid #D4DBE1;/*这个是解决兼容IE浏览器的属性*/
}
.tableDataGridFoot {
   border-collapse:collapse;
}
.theadStyle {
   background-repeat: repeat-x ;
}
公共css样式

  第二部分:自定义特性部分,该部分可以根据以后需求进行扩展。现在本部分只有皮肤风格枚举(enumSkin)、表格头部数据参数枚举(enumTHeadDataParamsType),具体代码实现如下:

 1 $.extend({
 2       enumDdataGrid: {
 3             //表格头部数据参数 类型
 4           enumTHeadDataParamsType: {
 5               number: 1,
 6               string: 2,
 7               ip: 3
 8           },
 9           //皮肤风格
10           enumSkin: {
11               classic: 1,     //经典
12               traditional: 2, //传统
13               gorgeous: 3     //绚丽
14           }
15       }
16 });
自定义特性

  第三部分:具体定义及实现部分。这部分是逻辑分装的主体,同时也是最难的部分。由于太多太多,所以只说一下思想。本次开发的插件使用 委托 事件句柄,思想开发。这样写的确实现了元素和事件间的解耦。当然这个也是模仿面向对象思想中的开发了。这个思想我在导航菜单中也有使用,并且这个思想也是我力推的思想。希望还不理解的猿们,好好学习一下,当你会了之后,你会感谢委托和事件句柄的,因为他让你的代码逻辑清晰了,代码也解耦了。。。自己去感受吧。我在代码中都加了注释,想必大家看也很好理解。但是逻辑还是有点复杂的,如果有想详细了解的可以联系我,在最下面我会将自己的联系QQ附上。^_^

  1 var dataGrid = function () {
  2         //参数定义
  3         this.defaultParams = {
  4             //参数定义
  5             id: "",
  6             data: null,
  7             url: null,
  8             tWidth: 1000,
  9             tHeadColor: "",
 10             tHeadBgColor: "",
 11             tHeadBgImgUrl: "",
 12             tHeadHeight: 32,
 13             tHeadStyle: "",
 14             tHeadCols: null,
 15             tHeadDataParams: {  //表格头部数据参数
 16                 field: "",
 17                 title: "",
 18                 width: "",
 19                 align: "",
 20                 sortable: "",
 21                 type: ""
 22             },
 23             tBodyColor: "",
 24             tBodyBgColor: "",
 25             tBodyHeight: 35,
 26             tBodyOddTrBgcolor: "", //基数行颜色
 27             tBodyEvenTrBgcolor: "", //偶数行颜色
 28             tBodyMouserOverBgcolor: "", //鼠标经过颜色
 29             tBodyMouserOutBgcolor: "",  //鼠标移出颜色
 30             tBodyTrSelectedBgColor: "yellow",  //被选中行颜色
 31             tFootColor: "",     //底部文字颜色
 32             tFootBgColor: "",   //底部背景
 33             tFootPosition: "right", //底部对其方式
 34             tBoolPage: true,    //是否分页
 35             tBoolCheckbox: true,    //是否显示check box
 36             pageCount: 10, //总页数
 37             pageSize: 10, //每页显示个数
 38             currentPage: 1, //当前页
 39             trTdentity: null,   //行标识
 40             tEnumDataGridSkin: null,  //选择皮肤风格
 41             tBoolRowNumbers: true,      //是否显示行号
 42             tBodyTrDblclickCallBack: $.noop //双击行 的回到函数           
 43         };
 44         this.options = {};
 45     };
 46     dataGrid.prototype = {
 47         constructor: dataGrid,
 48         init: function (params) {
 49             this.options = $.coverObject(this.defaultParams, params);
 50             this._init();
 51         },
 52         _init: function () {
 53             //初始化皮肤
 54             this.tInitializeSelectPSkin();
 55             //初始化元素
 56             this.tInitializeElement();
 57             this.tInitializeGetData();
 58             //创建table head
 59             this.createTableHead();
 60             //创建table body
 61             this.createTableBody();
 62             //选择是否分页
 63             if (this.options.tBoolPage) {
 64                 this.createTableFoot();
 65             }
 66             //选择是否显示多选按钮
 67             if (this.options.tBoolCheckbox) {
 68                 this.addCheckbox();
 69             }
 70             //是否显示行号
 71             if (this.options.tBoolRowNumbers) {
 72                 this.addRowNumbers();
 73             }
 74             //设置属性和样式
 75             this.setTableAttribute();
 76             //注册事件
 77             this._registerTableFootGoTo();
 78             this._registerTableFootFirstPage();
 79             this._registerTableFootLastPage();
 80             this._registerTableFootUpPage();
 81             this._registerTableFootNextPage();
 82             this._registerTbodyTrMouseover();
 83             this._registerTbodyTrMouseout();
 84             this._registerTbodyTrDblclick();
 85             this._registerTbodyTrCheckbox();
 86             this._registerTbodyTrClick();
 87             this._registerPageNumberKeyup();
 88             this._registerPageNumberPaste();
 89             this._registerPageNumberFocus();
 90             this._registerCheckboxCheckAll();
 91         },
 92 
 93         ///说明:
 94         ///     初始化选择皮肤
 95         tInitializeSelectPSkin: function () {
 96             switch (this.options.tEnumDataGridSkin) {
 97                 case $.enumDdataGrid.enumSkin.classic:
 98                     this.options.tWidth = 1000;
 99                     this.options.tHeadColor = "black";
100                     this.options.tHeadBgColor = "#e1e1e1";
101                     this.options.tHeadHeight = 32;
102                     this.options.tHeadBgImgUrl = "";
103                     this.options.tHeadStyle = "theadStyle";
104                     this.options.tBodyHeight = 35;
105                     this.options.tBodyOddTrBgcolor = "white";
106                     this.options.tBodyEvenTrBgcolor = "white";
107                     this.options.tBodyMouserOverBgcolor = "silver";
108                     this.options.tBodyTrSelectedBgColor = "yellow",
109                     this.options.tColNumber = 2;
110                     this.options.tColStyle = "lieStyle";
111                     break;
112                 case $.enumDdataGrid.enumSkin.traditional:
113                     this.options.tWidth = 1000;
114                     this.options.tHeadColor = "black";
115                     this.options.tHeadHeight = 32;
116                     this.options.tHeadBgImgUrl = "url(../Images/TableImg/tableHeadBg.jpg)";
117                     this.options.tHeadStyle = "theadStyle";
118                     this.options.tBodyHeight = 35;
119                     this.options.tBodyOddTrBgcolor = "white";
120                     this.options.tBodyEvenTrBgcolor = "#e1e1e1";
121                     this.options.tBodyMouserOverBgcolor = "silver";
122                     this.options.tBodyTrSelectedBgColor = "yellow",
123                     this.options.tColNumber = 2;
124                     this.options.tColStyle = "lieStyle";
125                     break;
126                 case $.enumDdataGrid.enumSkin.gorgeous:
127                     this.options.tWidth = 1000;
128                     this.options.tHeadColor = "black";
129                     this.options.tHeadHeight = 32;
130                     this.options.tHeadBgImgUrl = "url(../Images/TableImg/tableHeadBg.jpg)";
131                     this.options.tHeadStyle = "theadStyle";
132                     this.options.tBodyHeight = 35;
133                     this.options.tBodyOddTrBgcolor = "pink";
134                     this.options.tBodyEvenTrBgcolor = "#e1e1e1";
135                     this.options.tBodyMouserOverBgcolor = "silver";
136                     this.options.tBodyTrSelectedBgColor = "yellow",
137                     this.options.tColNumber = 2;
138                     this.options.tColStyle = "lieStyle";
139                     break;
140                 default:
141                     break;
142             }
143         },
144         ///说明:
145         ///     初始化元素
146         tInitializeElement: function () {
147             var id = this.options.id;
148             $("#" + id).attr({ "cellpadding": 1, "cellspacing": 0, "align": "center", "bordercolor": "#D4DBE1" });
149             $("#" + id).css("border-collapse", "collapse");
150             //添加区域
151             var headArea = "<thead gdThead=''></thead>";
152             var bodyArea = "<tbody gdTbody=''></tbody>";
153             var footArea = "<tfoot gdTfoot=''><tr><td></td></tr></tfoot>";
154             var area = headArea + bodyArea + footArea;
155             $("#" + id).html(area);
156             //设置自定义属性标识
157             $("#" + id).attr("datagrid", id);
158             $("table[datagrid $='" + id + "'] thead").attr("gdThead", id);
159             $("table[datagrid $='" + id + "'] tbody").attr("gdTbody", id);
160             $("table[datagrid $='" + id + "'] tfoot").attr("gdTfoot", id);
161             //判断是不是存在checkAll
162             if ($("input:checkbox[name='chk_All_" + id + "']").length > 0) {
163                 $("table[datagrid $='" + id + "'] thead tr").find("td:first").remove();
164             }
165             $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "']").empty();
166         },
167 
168         ///说明:
169         ///     获取数据源
170         tInitializeGetData: function () {
171             var optionsData = null;
172             var pageCount = 0;
173             var paramsData = {};
174 
175             //对是否分页做处理,当不分页的时候,需要在后台做判断的。
176             if (this.options.tBoolPage) {
177                 paramsData = { "pageSize": this.options.pageSize, "currentPage": this.options.currentPage };
178             }
179             $.ajax({
180                 type: "POST",
181                 url: this.options.url,
182                 data: paramsData,
183                 dataType: "json",
184                 async: false,
185                 success: function (result) {
186                     optionsData = result.Data;
187                     pageCount = result.PageCount;
188                 }
189             });
190             if (optionsData == null || optionsData.length < 1) {
191                 return;
192             }
193             this.options.data = optionsData;
194             this.options.pageCount = pageCount;
195         },
196 
197         ///说明:
198         ///     创建 table head
199         createTableHead: function () {
200             var id = this.options.id;
201             if (this.options.tHeadCols != null) {
202                 var cols = this.options.tHeadCols;
203                 var colsLen = cols.length;
204                 if (colsLen > 0) {
205                     var htmlHead = "";
206                     htmlHead += "<tr>";
207                     for (var i = 0; i < colsLen; i++) {
208                         var col = cols[i];
209                         var colLen = col.length;
210                         if (colLen > 0) {
211                             for (var j = 0; j < colLen; j++) {
212                                 this.options.tHeadDataParams = $.coverObject(this.options.tHeadDataParams, col[j]);
213                                 htmlHead += "<td width=" + this.options.tHeadDataParams.width + " align='" + this.options.tHeadDataParams.align + "'>";
214                                 htmlHead += this.options.tHeadDataParams.title;
215                                 htmlHead += "</td>";
216                             }
217                         }
218                     }
219                     htmlHead += "</tr>";
220                     $("table[datagrid $='" + id + "'] thead[gdThead $='" + id + "']").html(htmlHead);
221                 }
222             }
223         },
224 
225         ///说明:
226         ///     创建 table body
227         createTableBody: function () {
228             var options = this.options;
229             var id = options.id;
230             var data = options.data;
231             if ($("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "']").length <= 0) {
232                 return;
233             }
234             var htmlBody = "";
235             var colLen = $("table[datagrid $='" + id + "'] thead tr td").length;
236             $.each(data, function (i, ob) {
237                 htmlBody += "<tr trId='" + eval("ob." + options.trTdentity) + "' trRowNumber='" + (i + 1) + "' style='background-color:";
238                 if ((i + 1) % 2 == 0) {
239                     htmlBody += options.tBodyEvenTrBgcolor + "'>";
240                 } else {
241                     htmlBody += options.tBodyOddTrBgcolor + "' >";
242                 }
243                 var realityCount = 0;
244                 $.each(ob, function (j, d) {
245                     realityCount += 1;
246                     htmlBody += "   <td >" + d + "</td>";
247                 });
248                 //判断数据源中的数据列数是否 小于 table头部的列数
249                 if (realityCount < colLen) {
250                     var difference = colLen - realityCount;
251                     for (var j = 0; j < difference; j++) {
252                         htmlBody += "   <td></td>";
253                     }
254                 }
255                 htmlBody += "</tr>";
256             });
257 
258             $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "']").html(htmlBody);
259             $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "'] tr").attr("height", options.tBodyHeight); //设置行高
260 
261         },
262 
263         ///说明:
264         ///     创建 table foot
265         createTableFoot: function () {
266             var id = this.options.id;
267             if ($("table[datagrid $='" + id + "']").length <= 0) {
268                 return;
269             }
270             var tableFootHtml = "";
271             tableFootHtml += "<div class='gridData_tableFoot' style='float:" + this.options.tFootPosition + "'>";
272             tableFootHtml += "   <div id='tableFootGoTo_" + id + "'>转到</div>";
273             tableFootHtml += "   <div><input id='txtPageNumber_" + id + "' value='" + this.options.currentPage + "' style='width: 30px;height:auto;'/></div>";
274             tableFootHtml += "   <div id='tableFootFirstPage_" + id + "' >首页</div>";
275             tableFootHtml += "   <div id='tableFootUpPage_" + id + "' >上一页</div>";
276             tableFootHtml += "   <div id='tableFootNextPage_" + id + "' >下一页</div>";
277             tableFootHtml += "   <div id='tableFootLastPage_" + id + "' >末页</div>";
278             tableFootHtml += "   <div id='tableFootPageCount_" + id + "' style='cursor:default'>共" + this.options.pageCount + "页</div>";
279             tableFootHtml += "</div>";
280             $("table[datagrid $='" + id + "'] tfoot tr td").html(tableFootHtml);
281             $("#txtPageNumber_" + id).css("ime-mode", "disabled");//CSS设置输入法不可用
282         },
283         ///说明:
284         ///     添加多选框
285         addCheckbox: function () {
286             var id = this.options.id;
287             $("table[datagrid $='" + id + "'] thead tr").find("td:first").each(function (i) {
288                 $(this).before("<td align='center' width='30'><input type='checkbox' name='chk_All_" + id + "' value='checkbox'> </td>");
289             });
290             $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "'] tr").find("td:first").each(function (i) {
291                 $(this).before("<td align='center'><input type='checkbox' name='chk_" + i + "' chkNumber='" + (i + 1) + "' value='checkbox'> </td>");
292             });
293         },
294 
295         ///说明:
296         ///     添加行号
297         addRowNumbers: function () {
298             var id = this.options.id;
299             $("table[datagrid $='" + id + "'] thead tr").find("td:first").each(function (i) {
300                 $(this).before("<td align='center' style='background-color:#bababa' width='30'>&nbsp;</td>");
301             });
302             $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "'] tr").find("td:first").each(function (i) {
303                 $(this).before("<td align='center' style='background-color:#bababa;'>" + (i + 1) + "</td>");
304             });
305 
306         },
307 
308         ///说明:
309         ///     设置属性、样式
310         setTableAttribute: function () {
311             var id = this.options.id;
312             if ($("table[datagrid $='" + id + "']").length <= 0) {
313                 return;
314             }
315             $("table[datagrid $='" + id + "']").attr("width", this.options.tWidth);
316 
317             $("table[datagrid $='" + id + "'] thead").css("background", this.options.tHeadBgColor);
318             $("table[datagrid $='" + id + "'] thead").css("color", this.options.tHeadColor);
319             $("table[datagrid $='" + id + "'] thead").css("background-image", this.options.tHeadBgImgUrl);
320             $("table[datagrid $='" + id + "'] thead").css("height", this.options.tHeadHeight);
321             $("table[datagrid $='" + id + "'] thead").addClass(this.options.tHeadStyle);
322             $("table[datagrid $='" + id + "'] thead tr").css("height", this.options.tHeadHeight);
323             $("table[datagrid $='" + id + "'] tbody").css("background", this.options.tBodyBgColor);
324             $("table[datagrid $='" + id + "'] tbody").css("color", this.options.tBodyColor);
325             $("table[datagrid $='" + id + "'] tbody").addClass("tableBodyCur");
326             if ($("table[datagrid $='" + id + "']").length <= 0) {
327                 return;
328             }
329             $("table[datagrid $='" + id + "']").attr("width", this.options.tWidth);
330             $("table[datagrid $='" + id + "'] tfoot").css("background", this.options.tFootBgColor);
331             $("table[datagrid $='" + id + "'] tfoot").css("color", this.options.tFootColor);
332 
333             //设置列样式
334             if (this.options.tColStyle != "") {
335                 var options = this.options;
336                 var colLen = $("table[datagrid $='" + id + "'] thead tr td").length;
337                 $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "']").find("td").each(function (i) {
338                     if ((i + 1) % colLen == options.tColNumber) {
339                         $(this).addClass(options.tColStyle); //给区间加上特定样式 
340                     }
341                 });
342             }
343             var colLens = $("table[datagrid $='" + id + "'] thead tr td").length;
344             $("table[datagrid $='" + id + "'] tfoot tr td").attr("colspan", colLens);
345         },
346         /// 说明:
347         ///     跳转到首页
348         firstPage: function () {
349             var options = this.options;
350             options.currentPage = 1;
351             $("#txtPageNumber_" + options.id).val(options.currentPage);
352             this.jumpPage();
353         },
354         /// 说明:
355         ///     跳转到上一页
356         lastPage: function () {
357             var options = this.options;
358             if (options.currentPage === 1) {
359                 alert("已经到第一页了!");
360                 return;
361             }
362             options.currentPage = parseInt(options.currentPage) - 1;
363             $("#txtPageNumber_" + options.id).val(options.currentPage);
364             this.jumpPage();
365         },
366         /// 说明:
367         ///     跳转到下一页
368         nextPage: function () {
369             var options = this.options;
370             if (options.currentPage >= options.pageCount) {
371                 alert("超出了最大页数!");
372                 return;
373             }
374             options.currentPage = parseInt(options.currentPage) + 1;
375             $("#txtPageNumber_" + options.id).val(options.currentPage);
376             this.jumpPage();
377         },
378         /// 说明:
379         ///     跳转到末页
380         finalPage: function () {
381             var options = this.options;
382             options.currentPage = options.pageCount;
383             $("#txtPageNumber_" + options.id).val(options.currentPage);
384             this.jumpPage();
385         },
386         /// 说明:
387         ///     跳转到跳到某一页
388         jumpPage: function () {
389             var options;
390             if ($.getParam(arguments[0]) != "") {
391                 options = arguments[0];//这里特殊,判断是不是从PageNumber Keyup过来的
392             } else {
393                 options = this.options;
394             }
395             var id = options.id;
396 
397             $("#" + id).gridData.init(options);
398         },
399         /******************************(注册事件 begin)******************************/
400 
401         /// 说明:
402         ///     Go To
403         _registerTableFootGoTo: function () {
404             var handleEvent = $.delegate(this._handleTableFootGoTo, this);
405             $("#tableFootGoTo_" + this.options.id).click(handleEvent);
406         },
407         /// 说明:
408         ///     First Page
409         _registerTableFootFirstPage: function () {
410             var handleEvent = $.delegate(this._handleTableFootFirstPage, this);
411             $("#tableFootFirstPage_" + this.options.id).click(handleEvent);
412         },
413         /// 说明:
414         ///     Last Page
415         _registerTableFootLastPage: function () {
416             var handleEvent = $.delegate(this._handleTableFootLastPage, this);
417             $("#tableFootLastPage_" + this.options.id).click(handleEvent);
418         },
419         /// 说明:
420         ///     Up Page
421         _registerTableFootUpPage: function () {
422             var handleEvent = $.delegate(this._handleTableFootUpPage, this);
423             $("#tableFootUpPage_" + this.options.id).click(handleEvent);
424         },
425         /// 说明:
426         ///     Next Page
427         _registerTableFootNextPage: function () {
428             var handleEvent = $.delegate(this._handleTableFootNextPage, this);
429             $("#tableFootNextPage_" + this.options.id).click(handleEvent);
430         },
431         /// 说明:
432         ///     Tr Mouseover
433         _registerTbodyTrMouseover: function () {
434             var options = this.options;
435             $("table[datagrid $='" + this.options.id + "'] tbody tr").each(function () {
436                 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrMouseover, this, [{ options: options }]);
437                 $(this).mouseover(handleEvent);
438             });
439         },
440         /// 说明:
441         ///     Tr Mouseout
442         _registerTbodyTrMouseout: function () {
443             var options = this.options;
444             $("table[datagrid $='" + options.id + "'] tbody tr").each(function () {
445                 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrMouseout, this, [{ options: options }]);
446                 $(this).mouseout(handleEvent);
447             });
448         },
449         /// 说明:
450         ///     Tr Dblclick
451         _registerTbodyTrDblclick: function () {
452             var options = this.options;
453             $("table[datagrid $='" + options.id + "'] tbody tr").each(function () {
454                 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrDblclick, this, [{ options: options }]);
455                 var itemDblclickCallBack = $.delegate(options.tBodyTrDblclickCallBack, this, [{ id: $(this).attr("trId") }]);//回调事件
456                 $(this).dblclick(handleEvent);
457                 $(this).dblclick(itemDblclickCallBack);
458             });
459         },
460         /// 说明:
461         ///     Tr Checkbox
462         _registerTbodyTrCheckbox: function () {
463             var options = this.options;
464             //点击checkbox时候屏蔽tr的click事件,以防和tr的click事件重复
465             var objCheckAll = $("table[datagrid $='" + options.id + "'] tbody[gdTbody ='" + options.id + "'] tr").find("input:checkbox");
466             objCheckAll.each(function () {
467                 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrCheckbox, this, [{ options: options, objCheckAll: objCheckAll }]);
468                 $(this).click(function (event) {
469                     event.stopPropagation();
470                     handleEvent();
471                 });
472             });
473         },
474         /// 说明:
475         ///     Tr Click
476         _registerTbodyTrClick: function () {
477             var options = this.options;
478             $("table[datagrid $='" + options.id + "'] tbody tr").each(function () {
479                 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrClick, this, [{ options: options }]);
480                 $(this).click(handleEvent);
481             });
482         },
483         /// 说明:
484         ///     PageNumber Keyup
485         _registerPageNumberKeyup: function () {
486             var options = this.options;
487             $("#txtPageNumber_" + options.id).bind('keyup', function (e) {
488                 dataGrid.prototype._handlePageNumberKeyup(e, options);
489             });
490         },
491         /// 说明:
492         ///     PageNumber paste
493         _registerPageNumberPaste: function () {
494             var options = this.options;
495             $("#txtPageNumber_" + options.id).bind("paste", function () { //CTR+V事件处理 
496                 dataGrid.prototype._handlePageNumberPaste(options);
497             });
498         },
499         /// 说明:
500         ///     PageNumber Focus
501         _registerPageNumberFocus: function () {
502             var options = this.options;
503             $("#txtPageNumber_" + options.id).focus();
504         },
505         /// 说明:
506         ///     Checkbox CheckAll
507         _registerCheckboxCheckAll: function () {
508             var options = this.options;
509             var handleEvent = $.delegate(this._handleCheckboxCheckAll, this);
510             $("input:checkbox[name='chk_All_" + options.id + "']").change(handleEvent);
511         },
512         /******************************(注册事件 end)******************************/
513         /******************************(事件句柄 begin)******************************/
514         /// 说明:
515         ///     Go To
516         _handleTableFootGoTo: function () {
517             var options = this.options;
518             var pageNumber = $("#txtPageNumber_" + options.id).val();
519             if ($.IsNull(pageNumber)) {
520                 $("#txtPageNumber_" + options.id).val(options.currentPage);
521                 alert("输入的页数必须是数字且不能为空!");
522                 return;
523             }
524             var cuPage = parseInt($("#txtPageNumber_" + options.id).val());
525             if (cuPage > options.pageCount) {
526                 alert("超出了最大页数!");
527                 $("#txtPageNumber_" + options.id).val(options.currentPage);
528                 return;
529             }
530             options.currentPage = cuPage;
531             this.jumpPage();
532         },
533         /// 说明:
534         ///     First Page
535         _handleTableFootFirstPage: function () {
536             this.firstPage();
537         },
538         /// 说明:
539         ///     Last Page
540         _handleTableFootLastPage: function () {
541             this.finalPage();
542         },
543         /// 说明:
544         ///     Up Page
545         _handleTableFootUpPage: function () {
546             this.lastPage();
547         },
548         /// 说明:
549         ///     Next Page
550         _handleTableFootNextPage: function () {
551             this.nextPage();
552         },
553         /// 说明:
554         ///     Tr Mouseover
555         _handleTbodyTrMouseover: function (params) {
556             var options = params.options;
557             var obj = $(this).find("td input:checkbox");
558             if (obj.attr("checked")) {
559                 options.tBodyMouserOutBgcolor = options.tBodyTrSelectedBgColor;
560             }
561             $(this).css("background-color", options.tBodyMouserOverBgcolor);
562         },
563         /// 说明:
564         ///     Tr Mouseout
565         _handleTbodyTrMouseout: function (params) {
566             var options = params.options;
567             var obj = $(this).find("td input:checkbox");
568             if (obj.attr("checked")) {
569                 $(this).css("background-color", options.tBodyTrSelectedBgColor);
570             } else {
571                 var trRowNumber = parseInt($(this).attr("trRowNumber"));
572                 if (trRowNumber % 2 == 1) {
573                     $(this).css("background-color", options.tBodyOddTrBgcolor);
574                 } else {
575                     $(this).css("background-color", options.tBodyEvenTrBgcolor);
576                 }
577             }
578             if (obj.attr("checked")) {
579                 options.tBodyMouserOutBgcolor = options.tBodyTrSelectedBgColor;
580                 $(this).css("background-color", options.tBodyMouserOutBgcolor);
581             }
582         },
583         /// 说明:
584         ///     Tr Dblclick
585         _handleTbodyTrDblclick: function (params) {
586             var options = params.options;
587             var obj = $(this).find("td input:checkbox");
588             obj.attr("checked", true);
589             $(this).css("background-color", options.tBodyTrSelectedBgColor);
590         },
591         /// 说明:
592         ///     Tr Checkbox
593         _handleTbodyTrCheckbox: function (params) {
594             var options = params.options;
595             var objCheckAll = params.objCheckAll;
596             var chkAll = true;
597             objCheckAll.each(function (i, trCheck) {
598                 if (!trCheck.checked) {
599                     $("input:checkbox[name='chk_All_" + options.id + "']").attr("checked", false);
600                     chkAll = false;
601                 }
602             });
603             if (chkAll) {
604                 $("input:checkbox[name='chk_All_" + options.id + "']").attr("checked", true);
605             }
606             var objCheck = $(this);
607             var chkNumber = objCheck.attr("chkNumber");
608             var objTr = $("table[datagrid $='" + options.id + "'] tbody[gdTbody ='" + options.id + "'] tr[trRowNumber='" + chkNumber + "']");
609             dataGrid.prototype.setSelectedRowStyle(objCheck, objTr, options);
610         },
611         /// 说明:
612         ///     Tr Click
613         _handleTbodyTrClick: function (params) {
614             var options = params.options;
615             var objCheck = $(this).find("td input:checkbox");
616             objCheck.attr("checked", !objCheck.attr("checked"));
617             var objTr = $(this);
618             dataGrid.prototype.setSelectedRowStyle(objCheck, objTr, options);
619             var chkAll = true;
620             $("table[datagrid $='" + options.id + "'] tbody[gdTbody ='" + options.id + "'] tr").find("input:checkbox").each(function (i, trCheck) {
621                 if (!trCheck.checked) {
622                     $("input:checkbox[name='chk_All_" + options.id + "']").attr("checked", false);
623                     chkAll = false;
624                 }
625             });
626             if (chkAll) {
627                 $("input:checkbox[name='chk_All_" + options.id + "']").attr("checked", true);
628             }
629         },
630         /// 说明:
631         ///     PageNumber Keyup
632         _handlePageNumberKeyup: function (e, options) {
633             var curKey = e.which;
634             if (curKey == 13) {
635                 $("#txtPageNumber_" + options.id).blur(); //失去焦点,目的为了增强火狐的用户体验
636                 var pageNumber = $("#txtPageNumber_" + options.id).val();
637                 if ($.IsNull(pageNumber)) {
638                     $("#txtPageNumber_" + options.id).val(options.currentPage);
639                     alert("输入的页数必须是数字且不能为空!");
640                     return;
641                 }
642                 var cuPage = parseInt(pageNumber);
643                 if (cuPage > options.pageCount) {
644                     alert("超出了最大页数!");
645                     $("#txtPageNumber_" + options.id).val(options.currentPage);
646                     return;
647                 }
648                 options.currentPage = cuPage;
649                 dataGrid.prototype.jumpPage(options);
650             }
651             var objThis = $("#txtPageNumber_" + options.id);
652             objThis.val(objThis.val().replace(/\D|^0/g, ''));
653         },
654 
655         /// 说明:
656         ///     PageNumber paste
657         _handlePageNumberPaste: function (options) {
658             var objThis = $("#txtPageNumber_" + options.id);
659             objThis.val(objThis.val().replace(/\D|^0/g, ''));
660         },
661 
662         /// 说明:
663         ///     Checkbox CheckAll
664         _handleCheckboxCheckAll: function () {
665             var options = this.options;
666             var objThis = $("input:checkbox[name='chk_All_" + options.id + "']");
667             var objCheck = $("table[datagrid $='" + options.id + "'] tbody[gdTbody ='" + options.id + "'] tr").find("input:checkbox");
668             if (objThis.attr("checked")) {
669                 objCheck.each(function () {
670                     $(this).attr("checked", true);
671                 });
672                 $("table[datagrid $='" + options.id + "'] tbody tr").css("background-color", options.tBodyTrSelectedBgColor);
673                 return;
674             }
675             objCheck.each(function () {
676                 $(this).attr("checked", false);
677                 var trRowNumber = parseInt($(this).attr("chkNumber"));
678                 var objTr = $("table[datagrid $='" + options.id + "'] tbody tr[trRowNumber='" + trRowNumber + "']");
679                 if (trRowNumber % 2 == 1) {
680                     objTr.css("background-color", options.tBodyOddTrBgcolor);
681                 } else {
682                     objTr.css("background-color", options.tBodyEvenTrBgcolor);
683                 }
684             });
685         },
686         /******************************(事件句柄 end)******************************/
687         //设置选中行的样式
688         //  objCheck:选中行中的checkbox
689         //  objTr:选中行
690         //  options:参数
691         setSelectedRowStyle: function (objCheck, objTr, options) {
692             if (objCheck.attr("checked")) {
693                 objTr.css("background-color", options.tBodyTrSelectedBgColor);
694             } else {
695                 var trRowNumber = parseInt(objTr.attr("trRowNumber"));
696                 if (trRowNumber % 2 == 1) {
697                     objTr.css("background-color", options.tBodyOddTrBgcolor);
698                 } else {
699                     objTr.css("background-color", options.tBodyEvenTrBgcolor);
700                 }
701             }
702         }
703     };
具体定义及实现

    第四部分:对外开放部分。这部分代码很少也是老生常谈的代码了。定义对外开放,也就是一句话的事。代码如下:

1 $.fn.gridData = new dataGrid();
对外开放部分代码

  第五部分:具体使用部分。下面分两块代码叙说,第一块就是html页面,第二块就是js使用代码。代码如下:

1 <table id="aa" datagrid=""></table>
页面html代码
 1 $(function () {
 2     var options = {
 3         pageCount: 10, //总页数
 4         pageSize: 10,  //每页显示个数
 5         currentPage: 1, //当前页
 6         tBoolPage: true
 7     };
 8     options.tHeadCols = [
 9         [
10             { field: 'ID', title: '产品编号', width: 150, align: 'center', sortable: true },
11             { field: 'ProductName', title: '产品名称', width: 150, align: 'center', sortable: true },
12             { field: 'Description', title: '描述', width: 200, align: 'center' },
13             { field: 'Mark', title: '备注', width: 150, align: 'center' },
14             { field: 'ProductCategoryID', title: '产品类别', width: 150, align: 'center' },
15             { field: 'Price', title: '价格', width: 150, align: 'center' }
16         ]
17     ];
18     $("#aa").gridData.init({
19         id: "aa",
20         url: "../Product/GetPageProductInfo",
21         tHeadCols: options.tHeadCols,
22         tEnumDataGridSkin: $.enumDdataGrid.enumSkin.gorgeous,
23         tBoolRowNumbers: false,
24         trTdentity: "ID",        
25         pageSize: options.pageSize,
26         currentPage: options.currentPage,
27         pageCount: options.pageCount,
28         tBoolPage: options.tBoolPage,
29         tBodyTrDblclickCallBack: function (params) {
30             var id = params.id;
31             alert("this id is:" + id);
32         }
33     });
34 });
使用部分js代码

效果图

  下面是我贴的几个效果图,本人审美不好,随意加的样式,没有搭配感,还请各位看官一笑而过,只要知道有啥作用就好。

  效果图一(绚丽):

  效果图二(传统):

总结

  虽然写的不好,但是总结还是要的。本次开发属于重构之前代码开发。在此还是希望各位能注重重构,对自己代码负责。好的插件、好的代码也是重构出来的。哈哈,我是这么想的。不要嫌麻烦,也不要以为做的是无用功。

  文章比较长,很多知识点我也没有写详细。如果有需要源码的或者想共同探讨的同仁,随时联系我,QQ:296319075 ,注明园友就好,同时也希望大家也能提出宝贵意见,不吝赐教。秉承共同探讨、共同进步!如有转载,请注明出处,谢谢!^_^