华佗养生网
您的当前位置:首页原生javascript实现简单的datagrid数据表格_javascript技巧

原生javascript实现简单的datagrid数据表格_javascript技巧

来源:华佗养生网


简单的datagrid

1.排序 自定义排序方式

2.编辑

3.拖拽

4.分页

5.单选 多选(ctrl) 线性选(shift)

6.文字render 就是给文字着色 比如 大于0红色 小于0绿色

7.对列的显示隐藏

8.分组

只是一个示例 没有什么与后台的借口

其实可以写几个回调就行了 里面有loading条 可以在没返回结果前一直显示

代码如下:




table



1.排序 自定义排序方式


2.编辑


3.拖拽


4.分页


5.单选 多选(ctrl) 线性选(shift)


6.文字render 就是给文字着色 比如 大于0红色 小于0绿色


7.对列的显示隐藏


8.分组



下面是分组的 且有一个自定义排序方式 很好 一般 很差




(function(doc,undefined){
var win = this;
win.Sys = function (ua){
var b = {
ie: /msie/.test(ua) && !/opera/.test(ua),
opera: /opera/.test(ua),
safari: /webkit/.test(ua) && !/chrome/.test(ua),
firefox: /firefox/.test(ua),
chrome: /chrome/.test(ua)
},vMark = "";
for (var i in b) {
if (b[i]) { vMark = "safari" == i ? "version" : i; break; }
}
b.version = vMark && RegExp("(?:" + vMark + ")[\\/: ]([\\d.]+)").test(ua) ? RegExp.$1 : "0";
b.ie6 = b.ie && parseInt(b.version, 10) == 6;
b.ie7 = b.ie && parseInt(b.version, 10) == 7;
b.ie8 = b.ie && parseInt(b.version, 10) == 8;
return b;
}(win.navigator.userAgent.toLowerCase());

win.Sys.ie6&&doc.execCommand("BackgroundImageCache", false, true);

win.$$ = function(id){
return typeof id === 'string'
? doc.getElementById(id)
: id;
};
win.$q = function(name,parent){
return parent.getElementsByTagName(name);
}
win.$c = function(name,parent){
var elem = typeof name ==='object'? name : doc.createElement(name);
parent&&parent.appendChild(elem);
return elem;
};

win.addListener = function(element,e,fn){
!element.events&&(element.events = {});
element.events[e]&&(element.events[e][addListener.guid++]=fn)||(element.events[e] = {'0':fn});
element.addEventListener?element.addEventListener(e,fn,false):element.attachEvent("on" + e,fn);
};
win.addListener.guid = 1;
win.removeListener = function(element,e,fn){
var handlers = element.events[e],type;
if(fn){
for(type in handlers)
if(handlers[type]===fn){
element.removeEventListener?element.removeEventListener(e,fn,false):element.detachEvent("on" + e,fn);
delete handlers[type];
}
}else{
for(type in handlers){
element.removeEventListener?element.removeEventListener(e,handlers[type],false):element.detachEvent("on" + e,handlers[type]);
delete handlers[type];
}
}
};
win.fireEvent = function(element,eventName){
if(element[eventName]){
element[eventName]();
}else if(element.fireEvent){
element.fireEvent('on'+eventName);
}else if(doc.createEvent){
var evt = doc.createEvent("MouseEvents");
evt.initEvent(eventName, true, true);
element.dispatchEvent(evt);
}
};
win.setStyle = function(elems, style, value){
if( !elems.length ) elems = [elems];
if( typeof style == "string"){
style = value === undefined?{cssText:style}:(function(o){
return (o[style] = value,o);
})({});
};
each(elems,function(i,elem,style){
var value,name,ie=Sys.ie ;
for(name in style){
value = style[name];
if (name === "opacity" && ie) {
elem.style.filter = (elem.currentStyle.filter || "").replace( /alpha\([^)]*\)/, "" ) + "alpha(opacity=" + value * 100 + ")";
}else if(name === "float"){
elem.style[ ie ? "styleFloat" : "cssFloat" ] = value;
}else{
name = name.replace(/-([a-z])/ig, function(all, letter){
return letter.toUpperCase();
});
elem.style[name] = value;
}
}
},style);
};
win.setAttr = function(dom,attr){
if(typeof attr !== 'object')
return;
for(var name in attr)
dom.setAttribute(name,attr[name]);
}

var slice = Array.prototype.slice;
win.bind = function(object, fun) {
var args = slice.call(arguments).slice(2);
return function() {
return fun.apply(object, args);
};
};

win.bindAsEventListener = function(object, fun,args) {
var args = slice.call(arguments).slice(2);
return function(event) {
return fun.apply(object, [event || win.event].concat(args));
}
};
win.extend = function(){
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = true, options;
if ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
i = 2;
}
if ( typeof target !== "object" && Object.prototype.toString.call(target)!="[object Function]")
target = {};
for(;i if ( (options = arguments[ i ]) != null )
for(var name in options){
var src = target[ name ], copy = options[ name ];
if ( target === copy )
continue;
if ( deep && copy && typeof copy === "object" && !copy.nodeType ){
target[ name ] = arguments.callee( deep, src || ( copy.length != null ? [ ] : { } ), copy );
}
else if(copy !== undefined)
target[ name ] = copy;
}
}
return target;
};

win.Class = function(properties){
var _class = function(){
return (arguments[0] !== null && this.initialize && typeof(this.initialize) == 'function')
? this.initialize.apply(this, arguments)
: this;
};
_class.prototype = properties;
return _class;
};
win.each = function ( object, callback, args ) {
var name, i = 0, length = object.length;
if ( args ) {
args = Array.prototype.slice.call(arguments).slice(2);
if ( length === undefined ) {
for ( name in object )
if ( callback.apply( object[ name ],[name,object[ name ]].concat(args) ) === false )
break;
} else
for ( ; i < length; i++)
if ( callback.apply( object[ i ],[i,object[ i ]].concat(args)) === false ) //
break;
} else {
if ( length === undefined ) {
for ( name in object )
if ( callback.call( object[ name ], name, object[ name ] ) === false )
break;
} else
for ( var value = object[0];
i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
}
return object;
};
win.currentStyle = function(element){
return element.currentStyle || doc.defaultView.getComputedStyle(element, null);
};
win.objPos = function(elem){
var left = 0, top = 0, right = 0, bottom = 0,doc = elem ? elem.ownerDocument : doc;
if ( !elem.getBoundingClientRect || win.Sys.ie8 ) {
var n = elem;
while (n) { left += n.offsetLeft, top += n.offsetTop; n = n.offsetParent; };
right = left + elem.offsetWidth; bottom = top + elem.offsetHeight;
} else {
var rect = elem.getBoundingClientRect();
left = right = doc.documentElement.scrollLeft || doc.body.scrollLeft;
top = bottom = doc.documentElement.scrollLeft || doc.body.scrollLeft;
left += rect.left; right += rect.right;
top += rect.top; bottom += rect.bottom;
}
return { "left": left, "top": top, "right": right, "bottom": bottom };
};
win.contains = function(k,j){
return document.compareDocumentPosition
? k.compareDocumentPosition(j)&16
: k!==j&&k.contains(j);
};
win.hasClass = function(element, className){
return element.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'));
};
win.addClass = function(element, className){
if(!win.hasClass(element, className))
element.className.replace(/\s/g,'')===''
? element.className = className
: element.className+= " "+className;
};
win.removeClass = function(element, className){
win.hasClass(element, className)&&(element.className = element.className.replace(new RegExp('(\\s*|^)'+className+'(\\s*|$)'),' '));
}
})(document);
(function(doc,undefined){
var win = this,
uuid = -1;
/*
检查 字符串 中是否有key
如果有 且key后面是- 返回-后面的东西 否则返回true
检测不到返回false
*/
function checkReg(str,key){
var reg = new RegExp('(?:^|\\s)'+key+'\\b-?(.*?)(?:\\s|$)','i');
if(reg.exec(str)!=null){
return RegExp.$1===''?true:RegExp.$1;
}else{
return false;
}
};
/*
修改字符串中key对应的value
*/
function modify(str,key,value){
var reg = new RegExp('(^|\\s)('+key+'\\b-).*?(\\s|$)','i');
return str.replace(reg,'$1$2'+value+'$3');
};
win.easyGrid = new Class({
options : {
perPage : 10,
currPage : 0,
totalPage : 0,
count : 10,
page : 0,
isEdit : false,
widthConfig : {
td : null,
prevTd : null,
x : 0,
tdWidth : 0,
prevWidth: 0
},
cellMinWidth : 50,
sortType : {
int : function(v){return parseInt(v)},
float : function(v){return parseFloat(v)},
date : function(v){return v.toString()},
string : function(v){return v.toString()}
},
title : '标题'
},
initialize : function(options){
var op = extend(true,{},this.options),
options = this.defaults = extend(op,options),
container = this.container = $c('div',options.container),
dataConfig = options.dataConfig,
title = $c('div',container);
container.className = 'container';
title.innerHTML = options.title;
title.className = 'title';
this.primaryKey = options.primaryKey;
this.top = $c('div',container);
this.top.className = 'bar';
this.top.innerHTML = '跳转删除当前第页 总共页 一页条数据 共条数据';
var tabContainer = this.tabContainer = $c('div',container);
this.bottom = $c(this.top.cloneNode(true),container);
tabContainer.className = 'tabcontainer';
tabContainer.style.height = ~~options.container.offsetHeight - 83+'px';
var table = this.table = $c('table',tabContainer);
table.className = 't_a';
setAttr(table,{cellpadding :"0",cellspacing:"0",border :"0"});
this.thead = $c('thead',table);
this.tbody = $c('tbody',table);
this.tbody.style.display = 'none';
//loading条
this.loading_bg = $c('div',container);
this.loading_bg.className = 'loading';
setStyle(this.loading_bg,{
width : container.offsetWidth+2+'px',
height : container.offsetHeight+2+'px'
});

this.loading = $c('div',container);
this.loading.className ='loaddiv'
setStyle(this.loading,{
left:(container.offsetWidth/2-45) + 'px',
top:(container.offsetHeight/2-14) + 'px'
});
this.loading.innerHTML = 'Loading...';

//表格有多少列
this.colCount = options.fields.length;
// 数据源 形式是 [[],[],[],[],[],[]]
this.data = [];
// 当前请求到的数据源中 所有的分组头 形式是 [trdom1,trdom2]
this.grouphead = [];
//记录已经插入table的分组的tr [tr1,tr2,tr3]
this.insertTrs = [];
//列索引
//形式 [[td11,td12,td13,td14],[td21,td22,td23,td24]]
this.columns = [];

//true表示正序 false表示反序
this.ascSort = true;

//保存哪一列正在排序中的表头td
this.sortColumn = '';

//所有tr行 如果没有分组 形式是[tr1,tr2,tr3,tr4]
//如果有分组 [[tr1,tr2,tr3,tr4],[tr5,tr6,tr7,tr8]]
this.rows =[];

//一级菜单
this.popMenu = $c('div',doc.body);
this.popMenu.className = 'x-menu';
this.popMenu.innerHTML = '

  • 升序
  • 降序
  • 所有列
  • ';

    // 创建子菜单
    this.subPopMenu = $c('div',doc.body);
    this.subPopMenu.className = 'submenu';

    //表头的第一级弹出层是否打开 如果打开 保存 该td
    this.isMenuOpen = false;

    //保存列所有列中 某一列是否显示 或隐藏 num为计数器 看有多少列是现实中的
    //格式 clos: [ true,false,true,true] 1,3,4列显示 第2列隐藏
    this.isShowTrs = {
    num : 0,
    clos: []
    };

    // 创建拖动时显示的基准线
    this.line = $c('div',doc.body);
    this.line.className = 'line';

    //保存行
    //属性为uuid的递增量如 {1:dom,2:dom}
    this.selectedRows = {};

    // 保存最后选中的行
    this.lastSelectRow = {dom:null,index:null};

    this.currentEditRow = {index:0,dom:null};
    this.editData = [];
    this.editForm = $c('div',tabContainer);;
    setStyle(this.editForm,{
    position : 'absolute',
    display : 'none',
    'z-index': '120'
    });
    this.editTable = $c('table',this.editForm);
    setAttr(this.editTable,{
    cellspacing:'0',
    cellpadding:'0',
    border:'0'
    });
    var btnC = $c('div',this.editForm);
    btnC.className = 'editbtn';
    btnC.style.textAlign = 'center';
    btnC.innerHTML = '提交取消';
    this.editTable.className = 'edittable';
    var etr = $c('tr', $c('tbody',this.editTable));

    //创建一个 tr 的副本 因为后面生成tr的时候 可以直接复制节点
    this.copyTr = $c('tr');
    this.groupTr = $c('tr');
    this.groupTr.setAttribute('g','y');
    var ctd= $c('td',this.groupTr)
    ctd.setAttribute('colSpan',options.fields.length);

    var theadTr = $c('tr',this.thead),
    tWidth = 0,
    self = this,
    ul = $c('ul',this.subPopMenu),
    li;
    each(options.fields,function(i,o){
    var td = $c('td',theadTr),
    width = o.width?o.width:'80',
    div = i===0?'':'';
    td.innerHTML = [div,'',o.name,''].join('');
    setAttr(td,{clos:i,width:width,unselectable:'on','class':o.type === undefined?'':'type-'+o.type});
    self.createInput(i,o,etr);
    tWidth = tWidth + (~~width);
    li = $c('li',ul);
    li.innerHTML = [
    '',
    o.name,
    ''
    ].join('');

    //生成列索引 的 每列的第一项
    self.columns[i] = [td];
    $c('td',self.copyTr).setAttribute('unselectable','on');
    //计算出 所显示的列索引 和 一共多少列num
    self.isShowTrs.num++;
    self.isShowTrs.clos[i]=true;
    });

    setAttr(this.table,{width:tWidth+options.fields.length+1})

    //生成tbody里面的tr 只是生成 tr 根据perPage生成 它是显示当前一共有多少条数据的配置项
    var i=0,
    trsLen = options.perPage,
    frag = doc.createDocumentFragment(),
    arr = new Array(options.fields.length),
    tr,
    tds;
    for(;i tr = this.copyTr.cloneNode(true);
    tds = $q('td',tr);
    each(arr,function(i){
    //生成列索引的所有项
    self.columns[i].push(tds[i]);
    });
    $c(tr,frag);
    }
    this.tbody.appendChild(frag);
    if(typeof dataConfig === 'object'){
    setTimeout(function(){self.getDataCallBack(dataConfig);},5);
    }else{

    }
    /*
    表格拖拽
    表格排序
    等一些操作
    */
    addListener(this.thead,'click',bindAsEventListener(this,this.sortTable));
    addListener(this.thead,'mouseover',bindAsEventListener(this,this.theadOver));
    addListener(this.thead,'mouseout',bindAsEventListener(this,this.theadOut));
    addListener(this.thead,'mousedown',bindAsEventListener(this,this.dragWidth));

    /*
    绑定弹出层click事件 进行排序
    第2级菜单绑定 进行对列隐藏 显示
    */
    addListener(this.popMenu,'click',bindAsEventListener(this,this.menuClick));
    addListener(this.popMenu,'mouseover',bindAsEventListener(this,this.menuOver));
    addListener(this.subPopMenu,'click',bindAsEventListener(this,this.subMenuClick));

    /*
    放上去表格行的内容变粗
    */
    addListener(this.tbody,'mousemove',bindAsEventListener(this,this.rowHighlight,true));
    addListener(this.tbody,'mouseout',bindAsEventListener(this,this.rowHighlight,false));
    addListener(this.tbody,'mousedown',bindAsEventListener(this,this.selectRow,false));
    addListener(this.tbody,'dblclick',bindAsEventListener(this,this.editRow,false));

    addListener(btnC,'click',bindAsEventListener(this,this.modifyTr));

    addListener(this.top,'click',bindAsEventListener(this,this.pageBarClick));
    addListener(this.bottom,'click',bindAsEventListener(this,this.pageBarClick));
    },
    getDataCallBack : function(data){
    var options = this.defaults,
    self = this,
    totla = 0;

    this.data.length = 0;

    if(data.data){
    if(data.data[0].groupName){
    var grouphead = this.grouphead;
    grouphead.length = 0;

    each(data.data,function(i,o){
    var gtr = self.groupTr.cloneNode(true);
    $q('td',gtr)[0].innerHTML = o.groupName;
    grouphead.push(gtr);
    each(o.rows,function(j,d){
    //this.data中数据的最后一项是 索引
    d.push(i);
    self.data.push(d);
    });
    });
    this.showGroup=true;
    }else{
    each(data.data,function(i,o){
    self.data.push(o);
    });
    this.showGroup=false;
    }
    }else{
    return;
    }
    total = data.total
    ? data.total>=this.data.length
    ? data.total
    : this.data.length
    : this.data.length;
    this.writeMessage(total);
    this.buildTbody(options.currPage);
    },
    buildTbody : function(pageNum){
    if(this.data.length===0){
    this.tbody.style.display = 'none';
    return;
    }

    var i = 0,
    j = 0,
    self = this,
    data = this.data,
    options = this.defaults,
    trsLen = options.perPage,
    tdsLen = options.fields.length,
    tbody = this.tbody,
    trs = tbody.getElementsByTagName('tr'),
    start = pageNum*options.perPage,
    tr;
    this.rows.length = 0;

    if(this.showGroup){
    var group = {},
    index,
    arr = [],
    insertTrs = this.insertTrs;

    //清除掉之前插入的 分组tr
    insertTrs.length!=0&&each(insertTrs,function(i,o){
    self.tbody.removeChild(o);
    });
    insertTrs.length = 0;

    //遍历填充数据 给this.rows赋值
    var num = - 1;
    for(;i tr = trs[i];

    //如果没有数据了 就开始隐藏剩下的行
    if(!data[i+start]){
    tr.style.display = 'none';
    continue;
    }

    //做标记 tr 里面的内容对应data中哪条数据
    tr.setAttribute('dataIndex',i+start);
    tr.style.display = 'block';
    tds = tr.getElementsByTagName('td');
    //x为 分组的不同组的标识
    var x = data[i+start][data[i+start].length-1];
    //用来判断后来的数据和之前的数据是不是同一个组的
    //如果是同一个组的 选this.rows的最后一列添加
    //不是同一个组的创建一列添加

    num==x
    ? this.rows[this.rows.length-1].push(tr)
    : (this.rows[this.rows.length] = [tr],num = x);

    //用数组arr 记住每个分组的的第一个tr的位置 因为后面要插入tr头 i为位置 num为分组的序号
    !(num in group)&&(group[num] = i + start,arr.push([num,i]));
    for(j = 0;j td = tds[j];
    var txt = data[i+start][j] ===''?' ':data[i+start][j];
    render = options.fields[j].render;
    td.innerHTML = render
    ?render(txt)
    :txt;
    }
    tr.style.display = '';
    }

    each(arr.reverse(),function(i,o){
    insertTrs.push(self.grouphead[o[0]]);
    self.tbody.insertBefore(self.grouphead[o[0]],trs[o[1]]);
    });

    }else{
    for(;i tr = trs[i];
    //做标记 tr 里面的内容对应data中哪条数据
    tr.setAttribute('dataIndex',i+start);
    this.rows.push(tr);
    //没有数据的tr隐藏掉
    if(!data[i+start]){
    tr.style.display = 'none';
    continue;
    }
    tr.style.display = '';
    tds = $q('td',tr);

    for(j = 0;j var txt = data[i+start][j] ===''?' ':data[i+start][j];
    render = options.fields[j].render;
    tds[j].innerHTML = render
    ?render(txt)
    :txt;
    }
    }
    }

    options.currPage = pageNum;
    this.top.getElementsByTagName('span')[0].innerHTML=this.bottom.getElementsByTagName('span')[0].innerHTML = ~~pageNum+1;
    var topAs = this.top.getElementsByTagName('a'),
    bottomAs = this.bottom.getElementsByTagName('a');
    if(options.totalPage===1){
    bottomAs[0].className = topAs[0].className = 'first_div_no';
    bottomAs[1].className = topAs[1].className = 'prev_div_no';
    bottomAs[2].className = topAs[2].className = 'next_div_no';
    bottomAs[3].className = topAs[3].className = 'last_div_no';
    }else if(options.currPage===0){
    bottomAs[0].className = topAs[0].className = 'first_div_no';
    bottomAs[1].className = topAs[1].className = 'prev_div_no';
    bottomAs[2].className = topAs[2].className = 'next_div';
    bottomAs[3].className = topAs[3].className = 'last_div';
    }else if(options.currPage+1===options.totalPage){
    bottomAs[0].className = topAs[0].className = 'first_div';
    bottomAs[1].className = topAs[1].className = 'prev_div';
    bottomAs[2].className = topAs[2].className = 'next_div_no';
    bottomAs[3].className = topAs[3].className = 'last_div_no';
    }else{
    bottomAs[0].className = topAs[0].className = 'first_div';
    bottomAs[1].className = topAs[1].className = 'prev_div';
    bottomAs[2].className = topAs[2].className = 'next_div';
    bottomAs[3].className = topAs[3].className = 'last_div';
    }

    this.tbody.style.display = '';
    this.loading_bg.style.display ='none';
    this.loading.style.display ='none';

    },
    writeMessage : function(total){
    var options = this.defaults,
    base = total/options.perPage,
    topSpans = this.top.getElementsByTagName('span'),
    bottomSpans = this.bottom.getElementsByTagName('span');
    options.totalPage = base > parseInt(base)
    ? parseInt(base)+1
    : base;
    bottomSpans[0].innerHTML = topSpans[0].innerHTML = ~~options.currPage+1;
    bottomSpans[1].innerHTML = topSpans[1].innerHTML = options.totalPage;
    bottomSpans[2].innerHTML = topSpans[2].innerHTML = options.perPage;
    bottomSpans[3].innerHTML = topSpans[3].innerHTML = total;
    },
    sortTable : function(e){
    var elem = e.target || e.srcElement,
    self = this,
    options = this.defaults,
    elemName = elem.nodeName.toLowerCase(),
    showGroup = this.showGroup,
    tdElem = elem,
    name = elemName;

    //拖拽的时候可能会触发一次click 原因是ie下全部绑定在this.table上 代码见拖拽
    if($q('td',elem).length>1)
    return;
    if(name !== 'td'){
    while(name !== 'td'){
    tdElem = tdElem.parentNode;
    name = tdElem.nodeName.toLowerCase();
    }
    }
    var issort = checkReg(tdElem.className,'sort'),
    type = checkReg(tdElem.className,'type')

    //进行排序
    if(elemName !=='a'&&type){

    var frag = doc.createDocumentFragment();
    if(this.sortColumn!==tdElem&&this.sortColumn!==''){
    removeClass(this.sortColumn,'sort-asc');
    removeClass(this.sortColumn,'sort-desc');
    }
    if(issort){
    // 有分组,每组单独取反序 不分组,直接取反序
    showGroup
    ? each(this.rows,function(i,o){ o.reverse();})
    : this.rows.reverse();
    tdElem.className = modify(tdElem.className,'sort',issort==='asc'?'desc':'asc');
    }else{
    showGroup
    ? each(this.rows,function(i,o){
    o.sort(self.compare(tdElem.getAttribute('clos'),type));
    })
    : this.rows.sort(this.compare(tdElem.getAttribute('clos'),type));

    // 如果是正序排序,加上正序排列的标志。
    if(this.ascSort){
    addClass(tdElem,'sort-asc');
    }else{
    // 反序排列则将原有排序取反,并加上排序标志
    showGroup
    ? each(this.rows,function(i,o){ o.reverse();})
    : this.rows.reverse();
    addClass(tdElem,'sort-desc');
    }
    }

    // 将排序后的数据渲染到表格
    var insertTrs = this.insertTrs,
    len = insertTrs.length-1,
    arr = [];

    each(this.rows,function(i,tr){
    arr = [insertTrs[len-i]].concat(tr);
    showGroup
    ? each(arr,function(idx,obj){frag.appendChild(obj);})
    : frag.appendChild(tr);
    });
    this.tbody.appendChild(frag);
    this.sortColumn = tdElem;
    }

    //-------------------------------------------------------------------------------------
    /*
    如果点击的是表头中的 A 标签,则弹出菜单
    */
    if(elemName === 'a'){
    /*
    当在菜单外面点击的时候会执行 改函数
    用于清空 document的 click事件 隐藏层 去掉td,a的样式
    */
    function documentClick(){
    self.popMenu.style.display = 'none';
    self.subPopMenu.style.display = 'none';
    if(self.isMenuOpen){
    removeListener(document,'click');
    removeClass($q('div',self.isMenuOpen)[0],'theadfocus');
    $q('a',self.isMenuOpen)[0].style.display = 'none';
    }
    self.isMenuOpen = false;
    }

    var pos = objPos(elem),
    left = pos.left+Math.max(document.documentElement.scrollLeft,document.documentElement.scrollLeft),
    top = pos.top +Math.max(document.documentElement.scrollTop,document.documentElement.scrollTop)+ elem.offsetHeight,
    td = elem.parentNode.parentNode,
    lis = $q('li',this.popMenu);

    //如果this.isMenuOpen是真 表示 层是打开状态的 执行关闭相关的处理
    this.isMenuOpen&&documentClick();

    if(!checkReg(td.className,'type')){
    addClass(lis[0],'disabled');
    addClass(lis[1],'disabled');
    }else{
    removeClass(lis[0],'disabled');
    removeClass(lis[1],'disabled');
    }
    Sys.ie
    ? e.cancelBubble = true
    : e.stopPropagation();
    //当显示层的时候 吧该td附到this.isMenuOpen上
    this.isMenuOpen = td;
    addListener(document,'click',documentClick);
    setStyle(this.popMenu,{
    left : left+'px',
    top : top+'px',
    display :'block'
    });
    }
    },
    compare : function(n,type){
    var sortType = this.defaults.sortType,
    txt =Sys.ie?'innerText':'textContent';
    !sortType[type]&&(type = 'string');
    return function(a1,a2){
    a1 = sortType[type](a1.cells[n][txt]);
    a2 = sortType[type](a2.cells[n][txt]);
    return a1==a2?0:a1 }
    },
    pageBarClick : function(e){
    var elem = e.target || e.srcElement,
    options = this.defaults,
    typePage = elem.getAttribute('page'),
    isGo = elem.getAttribute('go');
    isDel = elem.getAttribute('del');

    if(typePage){
    var number = {
    start : 0,
    end : options.totalPage-1,
    next : options.currPage-1,
    pre : options.currPage+1
    }[typePage];
    this.toPage(number);
    }
    if(isDel){
    this.del();
    }

    if(isGo){
    var number = ~~elem.parentNode.getElementsByTagName('input')[0].value-1;
    this.toPage(number);
    }
    },
    toPage : function(num){
    if(typeof num !=='number'||isNaN(num))return;
    var options = this.defaults,
    self = this,
    dataConfig = options.dataConfig;
    //如果请求的分页数小于0就默认为0 如果打越最大分页数 就默认为最大分页数
    num>=options.totalPage
    &&(num = options.totalPage-1);
    num<0&&(num = 0);

    //s为当前面板的第一页 e为当前面板的最后
    var basePage = options.count/options.perPage,
    s = options.page*basePage,
    e = s + basePage-1;
    this.tbody.style.display = 'none';
    this.loading_bg.style.display = '';;
    this.loading.style.display = '';
    setTimeout(function(){self.buildTbody(num);},10);

    },
    del : function(){
    //做删除的时候需要有主键的索引 我全部保存在tr的
    var selectedRows = this.selectedRows,
    arr = []
    for(var name in selectedRows){
    arr.push(selectedRows[name].getAttribute('dataIndex'));
    }
    alert('选择了主键值为'+arr.join(','));
    },
    theadOver : function(e){
    var elem = e.target || e.srcElement;
    if(elem.nodeName.toLowerCase() === 'div'){
    $q('a',elem)[0].style.display = 'block';
    addClass(elem,'theadfocus');
    }
    },
    theadOut : function(e){
    var elem = e.target || e.srcElement,
    toElem = e.toElement||e.relatedTarget,
    elemName = elem.nodeName.toLowerCase();

    if(this.isMenuOpen && contains(this.isMenuOpen,elem))
    return;

    //如果离开了当前的td 隐藏显示出来的东西
    if(elemName === 'div'&& elem !== this.isMenuOpen){
    if(!contains(elem,toElem)){
    $q('a',elem)[0].style.display = 'none';
    removeClass(elem,'theadfocus');
    }
    }

    if(elemName === 'a' || elemName ==='span' || elemName === 'p'){
    var parent = elem.parentNode;
    if(!contains(elem,toElem)){
    $q('a',parent)[0].style.display = 'none';
    removeClass(parent,'theadfocus');
    }
    }
    },
    menuClick : function(e){
    var elem = e.target || e.srcElement,
    className = this.isMenuOpen.className;
    if(elem.nodeName.toLowerCase()==='a'){
    //如果td的样式中不存在type 也就是说不需要排序 则不进行排序 阻止事件冒泡
    if(!checkReg(className,'type')){
    Sys.ie
    ? e.cancelBubble = true
    : e.stopPropagation();
    return;
    }

    //如果a标签 的menuType
    显示全文