兼容FF和IE的动态table示例自写

  HTML的table结构如下:

  

复制代码 代码如下:

  <table id="Dy_table" width="760" cellpadding="0" style="border-top: solid 1px #9cf"

  class="tableStyle1" cellspacing="0">

  <tr>

  <th style="width: 40px">序号<input id="pageRows" name="pageRows" type="hidden" value="1" />

  <input type="hidden" name="HF_tableRows" id="HF_tableRows" value="1" /></th>

  <th style="width:120px">零件型号</th>

  <th style="width:130px">零件名称</th>

  <th style="width:45px">数量</th>

  <th style="width:70px">无税价</th>

  <th style="width:70px">含税价</th>

  <th style="width:70px">税额</th>

  <th style="width:70px">货款</th>

  <th style="width:70px">整额</th>

  <th style="width:60px">操作</th>

  </tr>

  <tr>

  <td>1</td>

  <td><input name='Dy_text_ljh' style='width: 110px' ondblclick='selectLj(this)' type='text'

  readonly='true' /><input name='Dy_hd_cpdm' type='hidden' onpropertychange='textChange(this)'

  title='产品代码' /><input name='Dy_hd_mxid' type='hidden' value='' title='该行的Id,用来修改和删除' /><input

  name='Dy_hd_rowState' type='hidden' value='1' title='该行的状态' /><input name='Dy_hf_ljgg'

  type='hidden' value='0' title='零件规格' /></td>

  <td><input name='Dy_text_cpmc' style='width: 120px' readonly='true' type='text' /></td>

  <td><input name='Dy_text_sl' value='1' onkeypress='onlyNumberIn1(this)' onkeyup='textChange(this)'

  style='width: 35px' type='text' /></td>

  <td><input name='Dy_text_wsj' style='width: 60px' type='text' readonly='true' /></td>

  <td><input name='Dy_text_hsj' style='width: 60px' type='text' readonly='true' /></td>

  <td><input name='Dy_text_se' style='width: 60px' type='text' readonly='true' /></td>

  <td><input name='Dy_text_hk' style='width: 60px' type='text' readonly='true' /></td>

  <td><input name='Dy_text_ze' style='width: 60px' type='text' readonly='true' /></td>

  <td><input name='del' type='button' value='删 除' class='input-button' onclick='delnode1(this)' /></td>

  </tr>

  </table>

  js代码如下:

  

复制代码 代码如下:

  function addEvent (o,c,h){

  if(o.attachEvent){

  o.attachEvent('on'+c,h);

  }else{

  o.addEventListener(c,h,false);

  }

  return true;

  }

  var selectRow;//页面级js变量,用来存被选中的行,好在弹出窗口中对该行赋值

  function addnode(){

  var table=document.getElementById("Dy_table");

  var tr=table.rows[1].cloneNode(true);

  for(var i=1;i<tr.childNodes.length-1;i++){

  for(var p=0;p<tr.childNodes[i].getElementsByTagName("input").length;p++){

  if(tr.childNodes[i].getElementsByTagName("input")[p].name=="Dy_hd_rowState")//行状态特殊对待

  tr.childNodes[i].getElementsByTagName("input")[p].value="1";

  else

  tr.childNodes[i].getElementsByTagName("input")[p].value="";

  }

  }

  var rowCount = table.rows[0].cells[0].getElementsByTagName("input")[1].value;//用户可见的行数

  tr.firstChild.innerHTML=parseInt(rowCount)+1;

  table.rows[0].cells[0].getElementsByTagName("input")[1].value = parseInt(rowCount)+1;//可见行数+1

  table.rows[0].cells[0].getElementsByTagName("input")[0].value = table.rows.length;//总行数,包含隐藏的

  var tbody=table.getElementsByTagName("tbody");

  if(tbody!=null){

  tbody[0].appendChild(tr);

  }else

  table.appendChild(tr);

  }

  //删除时的事件

  function delnode(){

  var table=document.getElementById("Dy_table");

  var rowCount = table.rows[0].cells[0].getElementsByTagName("input")[1].value;//用户可见的行数

  var row;//获取最后一个可见的row

  for( var i=table.rows.length-1; i>=0 ;i--){

  if(table.rows[i].style.display!="none")

  {

  row=table.rows[i];

  break;

  }

  }

  var rowId=row.cells[1].getElementsByTagName("input")[2].value;

  if( rowCount > 1 ){

  if(rowId=="")//新增的行未写入数据库时,直接删除

  {

  var tbody=table.getElementsByTagName("tbody");

  if(tbody!=null){

  tbody[0].removeChild(row);

  }else

  table.removeChild(row);

  table.rows[0].cells[0].getElementsByTagName("input")[1].value = parseInt(rowCount) - 1;

  }

  else//需要从数据库删除的,置上删除标记

  {

  row.style.display="none";

  row.cells[1].getElementsByTagName("input")[3].value = "2";

  table.rows[0].cells[0].getElementsByTagName("input")[1].value = parseInt(rowCount)-1;

  }

  }else{

  if(rowId == ""){//新增的行未写入数据库时,清空

  row.cells[1].getElementsByTagName("input")[0].value="";

  row.cells[1].getElementsByTagName("input")[1].value="";

  row.cells[1].getElementsByTagName("input")[2].value="";

  row.cells[1].getElementsByTagName("input")[3].value="";

  row.cells[1].getElementsByTagName("input")[4].value="";

  row.cells[2].getElementsByTagName("input")[0].value="";

  row.cells[3].getElementsByTagName("input")[0].value="1";

  row.cells[4].getElementsByTagName("input")[0].value="";

  row.cells[5].getElementsByTagName("input")[0].value="";

  row.cells[6].getElementsByTagName("input")[0].value="";

  row.cells[7].getElementsByTagName("input")[0].value="";

  row.cells[8].getElementsByTagName("input")[0].value="";

  }else{//需要从数据库删除的,置上删除标记

  row.style.display="none";

  row.cells[1].getElementsByTagName("input")[3].value = "2";

  table.rows[0].cells[0].getElementsByTagName("input")[1].value = parseInt(rowCount) - 1;

  addnode();

  }

  }

  setClf();

  }

  //删除时的事件

  function delnode1(o){

  var tr=o.parentNode.parentNode;

  var table=document.getElementById("Dy_table");

  var rowCount = table.rows[0].cells[0].getElementsByTagName("input")[1].value;//用户可见的行数

  var rowId=tr.cells[1].getElementsByTagName("input")[2].value;

  if( rowCount > 1 ){

  if(rowId=="")//新增的行未写入数据库时,直接删除

  {

  var tbody=table.getElementsByTagName("tbody");

  if(tbody!=null){

  tbody[0].removeChild(tr);

  }else

  table.removeChild(tr);

  table.rows[0].cells[0].getElementsByTagName("input")[1].value = parseInt(rowCount) - 1;

  }

  else

  {

  tr.style.display="none";

  tr.cells[1].getElementsByTagName("input")[3].value = "2";

  table.rows[0].cells[0].getElementsByTagName("input")[1].value = parseInt(rowCount) - 1;

  }

  }else{

  if(rowId==""){//新增的行未写入数据库时,直接清空

  tr.cells[1].getElementsByTagName("input")[0].value="";

  tr.cells[1].getElementsByTagName("input")[1].value="";

  tr.cells[1].getElementsByTagName("input")[2].value="";

  tr.cells[1].getElementsByTagName("input")[3].value="";

  tr.cells[1].getElementsByTagName("input")[4].value="";

  tr.cells[2].getElementsByTagName("input")[0].value="";

  tr.cells[3].getElementsByTagName("input")[0].value="1";

  tr.cells[4].getElementsByTagName("input")[0].value="";

  tr.cells[5].getElementsByTagName("input")[0].value="";

  tr.cells[6].getElementsByTagName("input")[0].value="";

  tr.cells[7].getElementsByTagName("input")[0].value="";

  tr.cells[8].getElementsByTagName("input")[0].value="";

  }else{//需要从数据库删除的,置上删除标记

  tr.style.display="none";

  tr.cells[1].getElementsByTagName("input")[3].value = "2";

  table.rows[0].cells[0].getElementsByTagName("input")[1].value = parseInt(rowCount) - 1;

  addnode();

  }

  }

  //以下循环用于从中间删除时更新表格行号

  for( var i= 1,p = 1; i < table.rows.length ;i++){

  if(table.rows[i].style.display!="none")

  {

  table.rows[i].cells[0].innerHTML = p;

  p++;

  }

  }

  setClf();

  }

  //修改时发生的事件,改变行状态

  function textChange(o){

  var tr=o.parentElement.parentElement;

  if(o.parentElement.parentElement.parentElement==null)return;//如果是新增加的行则返回

  var rowState = tr.cells[1].getElementsByTagName("input")[3].value;

  if( rowState == "1")

  return;

  else

  tr.cells[1].getElementsByTagName("input")[3].value = "3";

  setClf();

  }

  //提交前验证数据,保证没有重复的行

  function checkSameData(){

  var table=document.getElementById("Dy_table");

  for( var i= 1; i < table.rows.length ;i++){

  if(table.rows[i].style.display == "none"||table.rows[i].cells[1].getElementsByTagName("input")[1].value=="") continue;

  for( var p= i + 1; p < table.rows.length ;p++){

  if(table.rows[p].style.display == "none") continue;

  if(table.rows[i].cells[1].getElementsByTagName("input")[1].value.replace(/\s+$/g,"") ==

  table.rows[p].cells[1].getElementsByTagName("input")[1].value.replace(/\s+$/g,""))

  {alert("零件部分存在重复的项,不能保存!");return false;}

  }

  }

  return true;

  }

  var dialogWin;//零件窗口是否打开

  //选零件

  function selectLj(o){

  if(dialogWin == null){

  selectRow = o.parentNode.parentNode;//将行赋值给全局变量

  var cpxh = selectRow.cells[1].getElementsByTagName("input")[0].value;

  dialogWin = winOpen('selectLj.aspx?ljh='+cpxh);

  // window.open("../jddgl/Select_lj.aspx?ljh=" + cpxh,window,

  // "center:yes;dialogWidth:600px;dialogHeight:400px;help:no;status:no;");

  }

  }

  function winOpen(url){

  return window.open(url,'selectLj','resizable=1,status=0,menubar=0,scrollbars=1,height=400px,width=600px');

  }

  //计算table内费用

  function setClf(){}

  这算是对之前写的动态增加表格的改进,之前那个实在是学习了js没多久而作的失败作品。现在这个总算是可以兼容FF和IE了。在兼容的过程中,没少看标准dom规范,提高了不少知识,js操作dom翻看ms的DHTML手册的时候要注意它里面提到的方法和属性是不是标准的,最好用标准的。

  此动态table只要HTML里定好了table就可以动态的增减,不用关心它有多少个td,注意在第二个td里面加上相关的input hidden。动态增删只是一个表面的功能,这个table和dataset一样具有一个行状态,用行状态可以在服务器端对数据进行更新、删除和新增。1新增,2删除,3修改。只是用弹出窗口在FF和IE7下效果不行,不知道用iframe效果怎么样。

  IE下对于clone出来的tr不能通过cells来获取td的集合,FF下则是可以。由于tr内有input用了onpropertychange事件,在去掉新增的tr内input值的时候也会触发,所以在这个事件里用一个if排除了这种情况。浏览器的兼容还真是有些麻烦。FF下面还存在一个问题,从没有提交页面的情况下,FF重新载入页面的时候,服务器端控件的值会被保存下来,而IE下则是真的重新载入,页面上的任何值都不会保留。FF的这个保存服务器控件值的行为应该是它对asp.net支持存在问题,没有提交页面的情况下这是不应该发生的。