下面贴的代码只是贴出来TABLE中的移动效果,没有具体的录入界面。代码在OPERA9中和FF1中有问题(似乎onkeypress事件无效),但是放入INPUT等输入框之后可以正常使用。
测试方法:先点击某个单元格,然后通过方向键移动。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
</head>
<body>
<script type="text/javascript">
/**
Support:Opera7+
**/
var CTable = new Object();
//列数
CTable.colCount=0;
//行数
CTable.rowCount=0;
//Table Map
CTable.Map = null;
//前一单元格的行号,默认为-1
CTable.prevRow = -1;
//前一单元格的列号,默认为-1
CTable.prevCol = -1;
//当前行号,默认为-1
CTable.curRow=-1;
//当前列号,默认为-1
CTable.curCol=-1;
//待操作元素的Tag Name
CTable.Element="TD";
//载入table
CTable.Load = function(a_sID,a_sTagName){
var iRowCount=0, iColCount=0, i, j, m, n, iIndex=0, iCount;
var oTable = document.getElementById(a_sID);
//设置tble属性
if (oTable!=null) {
var tableMap = [];
for (i=0 ; i < oTable.rows[0].cells.length ; ++i ) {
iColCount += oTable.rows[0].cells[i].colSpan;
}
//获取总行数
iRowCount = oTable.rows.length;
//监听click事件
oTable.getElementsByTagName('tbody')[0].οnclick=CTable_setFocus;
//监听keydown事件
document.getElementsByTagName('body')[0].οnkeydοwn=CTable_moveFocus;
//列数
CTable.colCount = iColCount;
//行数
CTable.rowCount = iRowCount;
//table map start
//Init Table Map
var aCols=null, oCell;
for (i=0; i<iRowCount; ++i) {
aCols = new Array(iColCount);
tableMap.push(aCols);
}
for (i=0; i<iRowCount; ++i) {
iIndex=0;
for (j=0; j<iColCount; j+=oCell.colSpan) {
if (tableMap[i][j]==null) {
oCell = oTable.rows[i].cells[iIndex++];
for(m=i; m<i+oCell.rowSpan; ++m) {
for(n=j; n<j+oCell.colSpan; ++n) {
tableMap[m][n] = i+','+j;
}
}
tableMap[i][j] = oCell;
}
}
}
//table map结束
CTable.Map = tableMap;
}
};//end CTable.Load
//鼠标点击设置焦点 DOM:e.target
function CTable_setFocus(event){
var e = event || window.event;
var obj = e.target || e.srcElement, oParent = obj.parentNode;
var iCurRow = CTable.curRow, iCurCol = CTable.curCol;
var oPrevNode = CTable.getNode(CTable.prevRow,CTable.prevCol);
var iColCount = CTable.colCount;
var aMaps = CTable.Map;
if (oParent.tagName.toUpperCase() != "TR") {
return;
}
if (oPrevNode) {
oPrevNode.bgColor="#FFFFF0";
}
iCurRow = oParent.rowIndex;
for (var i=0; i<iColCount; i++){
if (aMaps[iCurRow][i]==obj) {
iCurCol = i;
break;
}
}
//设置结点的位置
CTable.curRow = iCurRow;
CTable.curCol = iCurCol;
if (CTable.prevRow ==-1 || CTable.prevCol==-1) {
CTable.prevRow = iCurRow;
CTable.prevCol = iCurCol;
}
obj.bgColor ="#FF0000";
obj.focus();
}
//移动焦点
function CTable_moveFocus(event) {
//获取当前结点
var e = event || window.event;
var oNode = e.target || e.srcElement;
var oNext = null;
switch (e.keyCode) {
case 37://2
oNext = CTable_getNextNode(2);
break;
case 38://↑ 0
oNext = CTable_getNextNode(0);
break;
case 13://回车
case 39://→3
oNext = CTable_getNextNode(3);
break;
case 40://↓1
oNext = CTable_getNextNode(1);
break;
}//end switch
//改变背景色
if (oNext) {
oNext.focus();
oNext.bgColor="#336699";
}
}//end moveFocus
//获取指定行、列号的单元格
CTable.getNode = function(a_iRow,a_iCol) {
//如果行号或列号小于零,则返回null
if (a_iRow<0 || a_iCol<0) {
return null;
}
//初始化数据
var oNode=null;
var aMaps = CTable.Map, aTemps=null;
var iRow = a_iRow, iCol=a_iCol;
var sTemp="";
//获取结点
while(true) {
oNode = aMaps[iRow][iCol];
sTemp=typeof(oNode);
if (sTemp.toLowerCase()=="string") {
aTemps=oNode.split(",");
iRow = aTemps[0];
iCol = aTemps[1];
} else {
break;
}
}
//函数返回值
return oNode;
};//end CTable.getNode
//获取一下结点
function CTable_getNextNode(a_iDirection) {
var oNode = null;
var iCol = CTable.curCol ,iRow=CTable.curRow;
var iRowCount = CTable.rowCount, iColCount=CTable.colCount;
var aMaps = CTable.Map, aTemps=null;
var iCurCol=iCol, iCurRow = iRow, iTemp;
var sTemp="", sStr="";
oNode = aMaps[iRow][iCol];
if (typeof(oNode)=="string") {
aTemps = oNode.split(",");
iCurRow = aTemps[0];
iCurCol = aTemps[1];
}
while (true) {
switch(a_iDirection) {
case 0:
iRow--;
break;
case 1:
iRow++;
break;
case 2:
iCol--;
if (iCol<0) {
iCol = iColCount-1;
iRow--;
}
break;
case 3:
iCol++;
if (iCol>=iColCount) {
iRow++;
iCol=0;
}
break;
}
if (iRow<0) {iRow=iRowCount-1;}
if (iRow>=iRowCount) {iRow=0;}
if ((iCurRow == iRow) && (iCurCol == iCol)) {
continue;
}
oNext = aMaps[iRow][iCol];
sTemp=typeof(oNext);
if (sTemp.toLowerCase()=="string") {
aTemps=oNext.split(",");
if ((iCurRow!=aTemps[0]) || (iCurCol!=aTemps[1])) {
oNext = CTable.getNode(iRow,iCol);
break;
}
continue;
}
break;
}; //end CTable.getNextNode
switch(a_iDirection) {
case 0://上
case 1://下
if (oNext.colSpan>1) {
iTemp = CTable.curCol;
CTable.prevCol = iTemp;
CTable.prevRow = CTable.curRow;
CTable.curRow = iRow;
} else {
CTable.prevCol = CTable.curCol;
CTable.prevRow = CTable.curRow;
CTable.curCol = iCol;
CTable.curRow = iRow;
}
break;
case 2://左
case 3://右
if (oNext.rowSpan>1) {
CTable.prevCol = CTable.curCol;
CTable.curCol = iCol;
iTemp = CTable.curRow;
CTable.curRow = iRow;
CTable.prevRow = iTemp;
} else {
CTable.prevCol = CTable.curCol;
CTable.prevRow = CTable.curRow;
CTable.curCol = iCol;
CTable.curRow = iRow;
}
break;
}
var oPrev = CTable.getNode(CTable.prevRow,CTable.prevCol);
if (oPrev) {
oPrev.bgColor="#FFFFFF";
}
return oNext;
}
//窗体载入函数
window.οnlοad=function() {CTable.Load("tblTest","TD");};
</script>
<table width="600" border="1" id="tblTest" name="tblTest">
<tr>
<td>0,0</td>
<td>0,1</td>
<td>0,2</td>
<td>0,3</td>
<td>0,4</td>
<td>0,5</td>
<td>0,6</td>
<td>0,7</td>
<td>0,8</td>
<td>0,9</td>
</tr>
<tr>
<td>1,0</td>
<td rowspan="3">1,1</td>
<td rowspan="2">1,2</td>
<td>1,3</td>
<td>1,4</td>
<td>1,5</td>
<td>1,6</td>
<td colspan="2" rowspan="3">1,7</td>
<td>1,8</td>
</tr>
<tr>
<td height="26">2,0</td>
<td>2,1</td>
<td>2,2</td>
<td colspan="2" rowspan="2">2,3</td>
<td>2,4</td>
</tr>
<tr>
<td>3,0</td>
<td>3,1</td>
<td>3,2</td>
<td>3,3</td>
<td>3,4</td>
</tr>
<tr>
<td>4,0</td>
<td>4,1</td>
<td colspan="5">4,2</td>
<td>4,3</td>
<td>4,4</td>
<td>4,5</td>
</tr>
<tr>
<td colspan="3">5,0</td>
<td>5,1</td>
<td colspan="2" rowspan="2">5,2</td>
<td>5,3</td>
<td>5,4</td>
<td>5,5</td>
<td>5,6</td>
</tr>
<tr>
<td colspan="2">6,0</td>
<td colspan="2">6,1</td>
<td rowspan="2">6,2</td>
<td>6,3</td>
<td rowspan="3">6,4</td>
<td>6,5</td>
</tr>
<tr>
<td colspan="2" rowspan="2">7,0</td>
<td>7,1</td>
<td colspan="2">7,2</td>
<td>7,3</td>
<td rowspan="2">7,4</td>
<td>7,5</td>
</tr>
<tr>
<td>8,0</td>
<td>8,1</td>
<td>8,2</td>
<td>8,3</td>
<td>8,4</td>
<td>8,5</td>
</tr>
<tr>
<td>9,0</td>
<td>9,1</td>
<td>9,2</td>
<td>9,3</td>
<td>9,4</td>
<td>9,5</td>
<td>9,6</td>
<td>9,7</td>
<td>9,8</td>
<td>9,9</td>
</tr>
</table>
</body>
</html>