注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 CCIE-Lab考试将新增10分钟..
 帮助

Ajax: Excel风格的HTML Table输入控件[四]:事件与单元格的遍历


2006-12-19 22:57:10
 标签:Ajax html Excel   [推送到技术圈]

 
本节介绍表格控件的事件处理,以及如何用键盘和鼠标遍历单元格,以及如何编辑、取消单元格的编辑。
 
1. 鼠标事件
首选取得当前单元格:
this.lastSelectedCell = Event.findElement(ev, "TD");
this.lastSelectedRow = this.lastSelectedCell.parentNode;
 
对每一个区域表格都注册鼠标单击事件与双击事件:
  this.centerBufferTable.onclick = this.onClick.bindAsEventListener(this);
  this.centerBufferTable.ondblclick = this.editCell.bindAsEventListener(this);
这里注册当双击时,就编辑单元格。如何编辑单元格将在第五节介绍。
当单击时,就选中当前单元格,同时不选中原来选中的单元格:
Element.removeClassName(this.lastSelectedCell, "cellselected");
Element.addClassName(this.lastSelectedCell, "cellselected");
同时,设置
 
另外还要考虑,如果是checkbox或radio风格的单元格,当单击时就改变其状态。
 
2. 键盘事件
Event.observe(document, 'keypress', this.onKeyPress.bindAsEventListener(this));
这里统一设置键盘事件,而不是每个区域表格都注册。
 
首先处理键盘事件时,使事件停止,不致再往下传播。
Event.stop(ev);很重要,不然当编辑单元格时,事件会传播到编辑控件。
 
同鼠标事件的处理,当前后左右遍历单元格时,就选中当前单元格,同时不选中原来选中的单元格。具体算法:
  //UP & DOWN
  if(ev.keyCode==40 || ev.keyCode==38){
   if (ev.keyCode==38) {
    if (this.lastSelectedRow.rowIndex > 0) {
     Element.removeClassName(this.lastSelectedCell, "cellselected");
     this.lastSelectedRow = this.lastSelectedRow.parentNode.rows[this.lastSelectedRow.rowIndex-1];
     this.lastSelectedCell = this.lastSelectedRow.cells[this.lastSelectedCell.cellIndex];
     Element.addClassName(this.lastSelectedCell, "cellselected");
    }
   }
   if (ev.keyCode==40) {
    if (this.lastSelectedRow.rowIndex < this.lastSelectedRow.parentNode.rows.length-1) {
     Element.removeClassName(this.lastSelectedCell, "cellselected");
     this.lastSelectedRow = this.lastSelectedRow.parentNode.rows[this.lastSelectedRow.rowIndex+1];
     this.lastSelectedCell = this.lastSelectedRow.cells[this.lastSelectedCell.cellIndex];
     Element.addClassName(this.lastSelectedCell, "cellselected");
    }
   }
  }
当回车事件时,如果原来是编辑状态,则停止编辑,否则编辑当前单元格。
  //ENTER
  else if(ev.keyCode==13) {
   if (this.editor != null)
    this.editStop(true);
   else
    this.editCell();
  }
TAB键和左右是相关的:
  //RIGHT LEFT
  else if(ev.keyCode==37 || ev.keyCode==39){
   if (ev.keyCode==37) {
    navLeft = true;
   }
   if (ev.keyCode==39) {
    navRight = true;
   }
  }
  //TAB
  else if(ev.keyCode==9  && !ev.shiftKey) {
   navRight = true;
   if (lastEditing) {
    nextEditing = true;
   }
  }
  else if(ev.keyCode==9  && ev.shiftKey) {
   navLeft = true;
   if (lastEditing) {
    nextEditing = true;
   }
  }
F2键编辑当前单元格:
  //F2
  else if(ev.keyCode==113) {
   this.editCell();
  }
ESC键取消编辑:
  //ESC
  else if(ev.keyCode==27) {
   this.editStop(false);
  }
SPACE键也是编辑当前单元格:
  //SPACE
  else if(ev.keyCode==32) {
   if (this.editor == null) {
    this.editCell();
   }
  }

3. 使当前单元格始终在可视区
当用键盘或鼠标遍历单元格时,如果当前单元格部分或全部不在可视区时,必须滚动使其在可视区内,同时协调相应的其他的区域滚动。
  var element = this.lastSelectedCell;
  var x = element.x ? element.x : element.offsetLeft;
        var y = element.y ? element.y : element.offsetTop;
  var divParent = this.lastSelectedRow.parentNode.parentNode.parentNode;
  if (divParent.scrollTop > y) {
   this.verticalBar.scrollTop = y;
   this.verticalScroll();
  }
  if (divParent.scrollTop + divParent.offsetHeight < y + element.offsetHeight) {
   this.verticalBar.scrollTop = y + element.offsetHeight - divParent.offsetHeight;
   this.verticalScroll();
  }
  if (divParent.scrollLeft > x) {
   this.horizonBar.scrollLeft = x;
   this.horizonScroll();
  }
  if (divParent.scrollLeft + divParent.offsetWidth < x + element.offsetWidth) {
   this.horizonBar.scrollLeft = x + element.offsetWidth - divParent.offsetWidth;
   this.horizonScroll();
  }




    文章评论
 
2007-02-14 17:44:09
adfadsf

 

发表评论

昵   称:
验证码:  点击图片可刷新验证码  博客过2级,无需填写验证码
内   容: