Updated for the previous version of dhDataGrid Ver1.0.0! 1. The fixed mode of the title bar and left sidebar is updated, and the expression mode is cancelled; 2. The sorting mode is updated, and it also supports the sorting of numbers, characters, dates, mixed numbers and characters, and Chinese characters; 3. Support skin change, you can customize the control style yourself; 4. Reserve [double-click], [right-click] functions; 5. Support IE, FF; CSS: /*dhdatagrid block style*/ #dhdatagrid {position:relative;width:500px;height:200px;background:white;margin :0px;padding:0px;overflow:hidden;border:1px inset;-moz-user-select:none;} /*dhdatagrid table global style*/ #dhdatagrid table {table-layout:fixed; margin:0px;} #dhdatagrid table td {height:18px;cursor:default;font-size:12px;font-family:verdana;overflow:hidden;white-space:nowrap;text-indent:2px;border -right:1px solid buttonface;border-bottom:1px solid buttonface;} #dhdatagrid table td .arrow {font-size:8px;color:#808080;} #dhdatagrid table .lastdata {border-right :none;} #dhdatagrid table .column {width:120px;cursor:default;background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040;border-bottom:1px solid # 404040;border-left:1px solid #fff;} #dhdatagrid table .over {width:120px;cursor:default;background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040 ;border-bottom:1px solid #404040;border-left:1px solid #fff;} #dhdatagrid table .sortdown {width:120px;cursor:default;background:buttonface;border-right:1px solid #ffffff; border-bottom:1px solid #ffffff;border-left:1px solid #404040;border-top:1px solid #404040;position:relative;left:1px;} #dhdatagrid table .dataover {background:#FAFAFA; } #dhdatagrid table .firstcolumn {width:30px;text-indent:0px;text-align:center;background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040;border- bottom:1px solid #404040;border-left:1px solid #fff;} #dhdatagrid table .lastcolumn {background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040;border- bottom:1px solid #404040;border-left:1px solid #fff;} /*dhdatagrid selected row style*/ #dhdatagrid table .selectedrow {background:highlight;color:white;} /*dhdatagrid header style*/ #dhdatagrid #titlecolumn {width:100%;position:absolute;top:0px;left:0px;z-index:3;} /*dhdatagrid left column style* / #dhdatagrid #slidecolumn {width:30px;position:absolute;top:0px;left:0px;z-index:2;} #dhdatagrid #slidecolumn td {width:30px;text-indent:0px ;text-align:center;background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040;border-bottom:1px solid #404040;border-left:1px solid #fff;} /*dhdatagrid content table body style*/ #dhdatagrid #datacolumn {width:100%;position:absolute;top:0px;left:0px;} /*dhdatagrid origin style*/ # dhdatagrid #zero {width:30px;height:18px;margin:0px;padding:0px;position:absolute;top:0px;left:0px;z-index:10;background:buttonface;border-top:1px solid #fff ;border-right:1px solid #404040;border-bottom:1px solid #404040;border-left:1px solid #fff;text-align:center;font-size:10px;color:#A19F92;} JS: function dhdatagrid(){ //author:dh20156; this.callname = "dhdg"; this.width = 500; this.height = 200; this.rid = "dhdatagrid"; this.columns = []; this.data = []; this.dblclick_fun = function(){} this.contextmenu_fun = function(){} this.parentNode = document.body; var dh = this; var framediv = null; var zerobj = null; var leftobj = null; var titleobj = null; var dataobj = null; var hbar = null; var vbar = null; var bgbar = null; //Change the initial position of the column width var ml = 0; //Change the initial width of the column width object var ow = 0; //Change the column width object var tdobj = null; //Current selection Fixed row index var nowrow = null; //Whether to change the vertical scroll bar position var changeposv = true; this.init = function(){ //init the data initial data var dgc = ""; if(this.columns.length>0){ dgc = "
"; for(var cc=0;cc dgc = "" this.columns[cc] "
"; } dgc = "
";
}
var dgs = "";
var dgd = "";
if(this.data.length> 0){
//First column
dgs = "
";
for(var r=0;r
dgs = "" (r 1) " "; dgd = "
"; for( var c=0;c dgd = "" this.data[r][c] " "; } dgd = "
"; } if(dgc==""){ dgc = "
"; for(var dc=0;dc dgc = "Expr" (dc 1) "
"; } dgc = "
"; } } //dhdatagrid frame frame var dgframe = document.createElement(" DIV"); dgframe.id = this.rid; dgframe.onmousedown = function(e){e=e||window.event;getrow(e);} dgframe.onmousemove = function (e){e=e||window.event;rsc_m(e);} if(document.attachEvent){ document.attachEvent("onmouseup",rsc_u); }else{ document.addEventListener("mouseup",rsc_u,false); } dgframe.oncontextmenu = function(){return false} dgframe.onselectstart = function(){return false} ae(dgframe); //dhdatagrid zero point zero point var dgzero = "
" //dhdatagrid slidecolumn first column var dgslide = ""; //dhdatagrid column title bar var dgcolumn = ""; //dhdatagrid data data var dgdata = ""; //dhdatagrid hbar 水平滚动条 var dghbar = document.createElement("DIV"); dghbar.id = "hbar"; dghbar.style.position = "absolute"; dghbar.style.width = "100%"; dghbar.style.height = "17px"; dghbar.style.top = this.height-17; dghbar.style.overflowX = "auto"; dghbar.style.zIndex = "10"; dghbar.onscroll = function(){scrh();} dghbar.innerHTML = "
"; //dhdatagrid vbar 垂直滚动条 var dgvbar = document.createElement("DIV"); dgvbar.id = "vbar"; dgvbar.style.position = "absolute"; dgvbar.style.width = "17px"; dgvbar.style.height = "100%"; dgvbar.style.left = this.width-17; dgvbar.style.overflowY = "auto"; dgvbar.style.zIndex = "10"; dgvbar.onscroll = function(){scrv();} dgvbar.innerHTML = "
"; //dhdatagrid bgbar 滚动条背景 var dgbgbar = document.createElement("DIV"); dgbgbar.id = "bgbar"; dgbgbar.style.background = "buttonface"; dgbgbar.style.position = "absolute"; dgbgbar.style.width = "100%"; dgbgbar.style.height = "17px"; dgbgbar.style.top = this.height-17; dgbgbar.style.overflowX = "auto"; dgbgbar.style.zIndex = "9"; dgbgbar.style.display = "none"; dgbgbar.innerHTML = " "; //appendChild dgframe.innerHTML = dgzero dgslide dgcolumn dgdata; dgframe.appendChild(dghbar); dgframe.appendChild(dgvbar); dgframe.appendChild(dgbgbar); this.parentNode.appendChild(dgframe); if(document.attachEvent){ document.attachEvent("onkeydown",updown); }else{ document.addEventListener("keydown",updown,false); } framediv = dgframe; zerobj = document.getElementById("zero"); leftobj = document.getElementById("slidecolumn"); titleobj = document.getElementById("titlecolumn"); dataobj = document.getElementById("datacolumn"); hbar = dghbar; vbar = dgvbar; bgbar = dgbgbar; var btt = getCurrentStyle(framediv,"borderTopWidth"); var btr = getCurrentStyle(framediv,"borderRightWidth"); var btb = getCurrentStyle(framediv,"borderBottomWidth"); var btl = getCurrentStyle(framediv,"borderLeftWidth"); var fh = getCurrentStyle(framediv,"height"); var zh = getCurrentStyle(zerobj,"height"); var zbt = getCurrentStyle(zerobj,"borderTopWidth"); var zbb = getCurrentStyle(zerobj,"borderBottomWidth"); if(document.all){ vbar.style.left = parseInt(vbar.style.left)-parseInt(btr)-parseInt(btl); }else{ framediv.style.height = parseInt(fh)-parseInt(btb)-parseInt(btt); zerobj.style.height = parseInt(zh)-parseInt(zbb)-parseInt(zbt); } hbar.style.top = parseInt(hbar.style.top)-parseInt(btb)-parseInt(btt); bgbar.style.top = parseInt(bgbar.style.top)-parseInt(btb)-parseInt(btt); } function getCurrentStyle(oElement, sProperty) { if(oElement.currentStyle){ return oElement.currentStyle[sProperty]; }else if(window.getComputedStyle){ sProperty = sProperty.replace(/([A-Z])/g, "-$1").toLowerCase(); return window.getComputedStyle(oElement, null).getPropertyValue(sProperty); }else{ return null; } } //设置块滚动条 this.setwh = function(){ hbar.style.display = "block"; vbar.style.display = "block"; hbar.childNodes[0].style.width = dataobj.offsetWidth; vbar.childNodes[0].style.height = dataobj.offsetHeight; if(hbar.childNodes[0].offsetWidth hbar.style.display = "none"; }else{ hbar.style.display = "block"; } if(vbar.childNodes[0].offsetHeight vbar.style.display = "none"; }else{ vbar.style.display = "block"; } if(hbar.childNodes[0].offsetWidth>hbar.offsetWidth && vbar.childNodes[0].offsetHeight>vbar.offsetHeight && changeposv){ bgbar.style.display = "block"; hbar.style.width = hbar.offsetWidth-17; vbar.style.height = vbar.offsetHeight-17; vbar.childNodes[0].style.height = vbar.childNodes[0].offsetHeight 17; changeposv = false; } if(hbar.childNodes[0].offsetWidth bgbar.style.display = "none"; hbar.childNodes[0].style.width = 0; hbar.style.width = hbar.offsetWidth 17; vbar.style.height = vbar.offsetHeight 17; changeposv = true; if(vbar.offsetHeight-dataobj.offsetHeight>dataobj.offsetTop && document.all){ leftobj.style.top = leftobj.offsetTop 17; dataobj.style.top = dataobj.offsetTop 17; } } } //鼠标滚轮,列表滚动事件 function mwEvent(e){ e=e||window.event; if(e.wheelDelta0){ vbar.scrollTop = 18; }else { vbar.scrollTop -= 18; } } function ae(obj){ if(document.attachEvent){ obj.attachEvent("onmousewheel",mwEvent); }else{ obj.addEventListener("DOMMouseScroll",mwEvent,false); } } //滚动条事件 function scrv(){ leftobj.style.top = -(vbar.scrollTop); dataobj.style.top = -(vbar.scrollTop); } function scrh(){ titleobj.style.left = -(hbar.scrollLeft); dataobj.style.left = -(hbar.scrollLeft); } //选择行 function getrow(e){ e=e||window.event; var esrcobj = e.srcElement?e.srcElement:e.target; if(esrcobj.parentNode.tagName=="TR"){ var epobj = esrcobj.parentNode; var eprowindex = epobj.rowIndex; if(eprowindex!=0){ if(nowrow!=null){ dataobj.rows[nowrow].className = ""; } dataobj.rows[eprowindex].className = "selectedrow"; nowrow = eprowindex; } } } //更改列宽 this.rsc_d = function(e,obj){ var px = document.all?e.offsetX:e.layerX-obj.offsetLeft; if(px>obj.offsetWidth-6 && px e=e||window.event; obj=obj||this; ml = e.clientX; ow = obj.offsetWidth; tdobj = obj; if(obj.setCapture){ obj.setCapture(); }else{ e.preventDefault(); } }else{ if(nowrow!=null){ dataobj.rows[nowrow].className = ""; } if(obj.getAttribute("sort")==null){ obj.setAttribute("sort",0); } var sort = obj.getAttribute("sort"); if(sort==1){ dgsort(obj,true); obj.setAttribute("sort",0); }else{ dgsort(obj,false); obj.setAttribute("sort",1); } obj.className = "sortdown"; } } this.mouseup = function(obj){ obj.className = "over"; } function rsc_m(e){ if(tdobj!=null){ e=e||window.event; var newwidth = ow-(ml-e.clientX); if(newwidth>5){ tdobj.style.width = newwidth; dataobj.rows[0].cells[tdobj.cellIndex].style.width = newwidth; }else{ tdobj.style.width = 5; dataobj.rows[0].cells[tdobj.cellIndex].style.width = 5; } dh.setwh(); scrh(); } } function rsc_u(e){ if(tdobj!=null){ e=e||window.event; var newwidth = ow-(ml-e.clientX); if(newwidth>5){ tdobj.style.width = newwidth; dataobj.rows[0].cells[tdobj.cellIndex].style.width = newwidth; }else{ tdobj.style.width = 5; dataobj.rows[0].cells[tdobj.cellIndex].style.width = 5; } if(tdobj.releaseCapture){ tdobj.releaseCapture(); } ml = 0; ow = 0; tdobj = null; } dh.setwh(); scrh(); } this.cc = function(e,obj){ var px = document.all?e.offsetX:e.layerX-obj.offsetLeft; if(px>obj.offsetWidth-6 && px obj.style.cursor = "col-resize"; }else{ obj.style.cursor = "default"; } } this.over = function(obj){ obj.className = "over"; } this.out = function(obj){ obj.className = "column"; } this.dataover = function(obj){ if(obj.rowIndex!=nowrow){ obj.className = "dataover"; } } this.dataout = function(obj){ if(obj.rowIndex!=nowrow){ obj.className = ""; } } //键盘Up & Down事件 function updown(e){ e=e || window.event; e=e.which || e.keyCode; var rl = dh.data.length; switch(e){ case 38://Up; if(nowrow!=null && nowrow>1){ vbar.scrollTop -= 18; dataobj.rows[nowrow].className = ""; nowrow -= 1; dataobj.rows[nowrow].className = "selectedrow"; }; break; case 40://Down; if(nowrow!=null && nowrow vbar.scrollTop = 18; dataobj.rows[nowrow].className = ""; nowrow = 1; dataobj.rows[nowrow].className = "selectedrow"; }; break; default:break; } } function dti(s){ var n = 0; var a = s.match(/d /g); for(var i=0;i if(a[i].length a[i] = "0" a[i]; } } n = a.join(""); return n; } //排序 function dgsort(obj,asc){ var rl = dh.data.length; var ci = obj.cellIndex; var rowsobj = []; for(var i=1;i rowsobj[i-1] = dataobj.childNodes[0].rows[i]; } rowsobj.sort(function(trObj1,trObj2){ if(!isNaN(trObj1.cells[ci].innerHTML.charAt(0)) && !isNaN(trObj2.cells[ci].innerHTML.charAt(0))){ if(asc){ return dti(trObj1.cells[ci].innerHTML)-dti(trObj2.cells[ci].innerHTML); }else{ return dti(trObj2.cells[ci].innerHTML)-dti(trObj1.cells[ci].innerHTML); } }else{ if(asc){ return trObj1.cells[ci].innerHTML.localeCompare(trObj2.cells[ci].innerHTML); }else{ return trObj2.cells[ci].innerHTML.localeCompare(trObj1.cells[ci].innerHTML); } } }); for(var i=0;i dataobj.childNodes[0].appendChild(rowsobj[i]); } for(var c=1;c obj.parentNode.cells[c].childNodes[1].innerHTML = ""; } if(asc){ obj.childNodes[1].innerHTML = "▲"; }else{ obj.childNodes[1].innerHTML = "▼"; } } } 注: DEMO(演示):http://www.jxxg.com/dh20156/dhdatagrid/ 原文:http://blog.csdn.net/dh20156/archive/2007/02/08/1505050.aspx 另外一个封装的很简单的grid by 秦皇也爱JS <script> <BR>var GridData = { <BR> title: ["姓名","性别","年龄","学历","特长"], <BR> type: [0,1,0,1,0], //编辑框类型 ŀ--textbox Ł---select <BR> order: [-1,-1,-1,-1,-1], //排序类型 Ł----升序 -1---降序 <BR> data: [["张三","男",27,"本科","足球"], <BR> ["YM","男",26,"本科","中锋"], <BR> ["McGrady","男",28,"博士","前锋"], <BR> ["James","男",25,"本科","小前锋"], <BR> ["Good","女",21,"高中","商品"], <BR> ["Fut","男",22,"本科","WAR3"], <BR> ["Keens","男",37,"高中","SC"], <BR> ["Gruby","女",32,"本科","SC"], <BR> ["Grrr","男",19,"硕士","SC"], <BR> ["Sky","男",22,"本科","WAR3"], <BR> ["Moon","男",25,"本科","WAR3"]] <BR>}; <br><br>var 性别 = ["男", "女"]; <BR>var 学历 = ["高中", "本科", "硕士", "博士"]; <br><br>function MyGrid(data, cnt){ <BR> MyGrid.backColor = "#fdfdfd"; <BR> MyGrid.hoverColor = "#edfae9"; <BR> MyGrid.clickColor = "#e1e6f1"; <br><br> this.datas = data; <BR> this.container = cnt; <BR> this.table; <BR> this.curRow; <BR> this.curCell; <BR> this.editTools = [document.body.appendChild(document.createElement("input")),document.body.appendChild(document.createElement("select"))]; <BR> var CurGrid = this; <BR> this.load = function(){ //grid重画模块 <BR> /** 加载table **/ <BR> var tbStr = []; <BR> tbStr.push("<table cellspacing='1'><tr height='25'>"); <BR> for(var o in this.datas.title){ <BR> tbStr.push("<th>" + this.datas.title[o] + (this.datas.order[o]==1?"↑":"↓") + ""); <BR> } <BR> tbStr.push(""); <br><br> for(var i in this.datas.data){ <BR> tbStr.push("<tr bgcolor=" + MyGrid.backColor + " height='25'>"); <BR> for(var j in this.datas.data[i]){ <BR> tbStr.push("<td>" + this.datas.data[i][j] + ""); <BR> } <BR> tbStr.push(""); <BR> } <br><br> tbStr.push(""); <BR> this.container.innerHTML = tbStr.join(""); <BR> this.table = this.container.firstChild; <br><br> /** 设置编辑工具 **/ <BR> this.editTools[0].onblur = function(){ <BR> CurGrid.curCell.removeChild(CurGrid.curCell.firstChild) <BR> CurGrid.curCell.appendChild(document.createTextNode(this.value)); <BR> if(isNaN(CurGrid.datas.data[CurGrid.curCell.parentNode.rowIndex-1][CurGrid.curCell.cellIndex])){ <BR> CurGrid.datas.data[CurGrid.curCell.parentNode.rowIndex-1][CurGrid.curCell.cellIndex] = this.value; <BR> }else{ <BR> CurGrid.datas.data[CurGrid.curCell.parentNode.rowIndex-1][CurGrid.curCell.cellIndex] = Number(this.value) <BR> } <br><br> this.value = ""; <BR> this.style.display = "none"; <BR> } <br><br> this.editTools[1].onblur = function(){ <BR> this.options.length = 0; <BR> this.style.display = "none"; <BR> } <br><br> this.editTools[1].onchange = function(){ <BR> CurGrid.curCell.removeChild(CurGrid.curCell.firstChild) <BR> CurGrid.curCell.appendChild(document.createTextNode(this.value)); <BR> CurGrid.datas.data[CurGrid.curCell.parentNode.rowIndex-1][CurGrid.curCell.cellIndex] = this.value; <br><br> this.options.length = 0; <BR> this.style.display = "none"; <BR> } <br><br> /** 设置单元格 **/ <BR> for(var r=1; r<this.table.rows.length;r++){ <BR> this.table.rows[r].onmouseover = function(){ this.style.backgroundColor = MyGrid.hoverColor; } <BR> this.table.rows[r].onmouseout = function(){ <BR> if(CurGrid.curRow!=this) this.style.backgroundColor = MyGrid.backColor; <BR> else this.style.backgroundColor = MyGrid.clickColor; <BR> } <br><br> for(var c=0;c<this.table.rows[r].cells.length;c++){ <BR> this.table.rows[r].cells[c].onclick = function(){ <BR> if(CurGrid.curRow) CurGrid.curRow.style.backgroundColor = MyGrid.backColor; <BR> CurGrid.curRow = this.parentNode; <BR> this.parentNode.style.backgroundColor = MyGrid.clickColor; <BR> } <br><br> this.table.rows[r].cells[c].ondblclick = function(){ <BR> //alert("( " + this.cellIndex + "," + this.parentNode.rowIndex + " ) " + this.firstChild.data); <BR> CurGrid.curCell = this; <br><br> CurGrid.editTools[CurGrid.datas.type[this.cellIndex]].style.display = "block"; <BR> CurGrid.editTools[CurGrid.datas.type[this.cellIndex]].style.width = this.offsetWidth; <BR> CurGrid.editTools[CurGrid.datas.type[this.cellIndex]].style.height = this.offsetHeight; <BR> CurGrid.editTools[CurGrid.datas.type[this.cellIndex]].style.left = getAbsPos(this).leftx - CurGrid.container.scrollLeft; <BR> CurGrid.editTools[CurGrid.datas.type[this.cellIndex]].style.top = getAbsPos(this).topy - CurGrid.container.scrollTop; <BR> CurGrid.editTools[CurGrid.datas.type[this.cellIndex]].focus(); <br><br> if(CurGrid.datas.type[this.cellIndex] == 0){ <BR> CurGrid.editTools[CurGrid.datas.type[this.cellIndex]].select(); <BR> }else if(CurGrid.datas.type[this.cellIndex] == 1){ <BR> CurGrid.loadSelect(CurGrid.datas.title[this.cellIndex]); <BR> } <br><br> CurGrid.editTools[CurGrid.datas.type[this.cellIndex]].value = this.firstChild.data; <BR> } <BR> } <BR> } <br><br> for(var g=0; g<this.table.rows[0].cells.length;g++){ <BR> this.table.rows[0].cells[g].onclick = function(){ <BR> CurGrid.datas.order[this.cellIndex] = -CurGrid.datas.order[this.cellIndex]; <BR> CurGrid.sort(this.cellIndex, CurGrid.datas.order[this.cellIndex]); <BR> } <BR> } <BR> } <br><br> this.sort = function(n, type){ //排序 <BR> this.datas.data = this.datas.data.sort(function(x,y){if (x[n]>y[n]){return type;}else if(x[n]<y[n]){return -type;}else{return 0;}}); <BR> this.load(); <BR> } <br><br> this.delRow = function(){ //删除行 <BR> this.datas.data.splice(this.curRow.rowIndex-1, 1); <BR> this.table.deleteRow(this.curRow.rowIndex); <BR> } <br><br> this.loadSelect = function(type){ //读取下拉框内容 <BR> var opts = this.editTools[1].options; <BR> for(var o in eval(type)){ <BR> var opt = document.createElement("option"); <BR> opt.value = opt.text = eval(type)[o]; <BR> opts.add(opt); <BR> } <BR> } <BR>} <br><br>var grid; <BR>window.onload = loadGrid; <br><br>function loadGrid(){ <BR> grid = new MyGrid(GridData, $("panel")); <BR> grid.load(); <BR>} <br><br>function $(id){ <BR> return document.getElementById?document.getElementById(id):eval(id); <BR>} <br><br>function getAbsPos(obj){ <BR> var objResult = new Object(); <BR> objResult.topy = obj.offsetTop; <BR> objResult.leftx = obj.offsetLeft; <BR> while( obj = obj.offsetParent){ <BR> objResult.topy += obj.offsetTop; <BR> objResult.leftx += obj.offsetLeft; <BR> } <BR> return objResult; <BR>} <br><br></script>