网页中的虚拟table

在网页中用table加载大量数据是件痛苦的事,效率太低了,对内存的占用也太大了。联想到C#中用到的DataGridView的虚拟模式,试着在网页中用html+js实现了一个,没仔细测,通用性封装也不好,给大家抛块砖而已。

  
  
  
  
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"
  2. <html> 
  3. <head>  
  4.  <title>表格虚拟模式</title> 
  5.  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  6.  <style type="text/css">  
  7.  * { 
  8.    font-size:12px; 
  9.   padding:0; 
  10.   margin:0; 
  11.  } 
  12.  html,body{ 
  13.   height:100%; 
  14.  } 
  15.  #wrapperHead{ 
  16.   width:583px; 
  17.   position:absolute; 
  18.   top:21px; 
  19.   left:41px; 
  20.   z-index:100; 
  21.   overflow:hidden; 
  22.  } 
  23.  #wrapperBody{ 
  24.   width:600px; 
  25.   height:90%; 
  26.   overflow-y:auto; 
  27.   overflow-x:auto; 
  28.   border:solid 1px black; 
  29.   position:absolute; 
  30.   top:20px; 
  31.   left:40px; 
  32.  } 
  33.  table{ 
  34.   width:700px; 
  35.   border-collapse:collapse; 
  36.   table-layout:fixed; 
  37.  } 
  38.  tr:hover{ 
  39.   background-color:#eee; 
  40.  } 
  41.  td{ 
  42.   padding:3px; 
  43.   white-space:nowrap; 
  44.   overflow:hidden; 
  45.   text-overflow:ellipsis; 
  46.   cursor:default
  47.   height:21px; 
  48.  } 
  49.  th{ 
  50.   padding:3px; 
  51.   white-space:nowrap; 
  52.   overflow:hidden; 
  53.   text-overflow:ellipsis; 
  54.   cursor:default
  55.   background-color:#06c; 
  56.   color:white; 
  57.   border-left:solid 1px darkgray; 
  58.   height:15px; 
  59.  } 
  60.  #msg{ 
  61.   position:absolute; 
  62.   top:5px; 
  63.   left:10px; 
  64.  } 
  65.  .btn{ 
  66.   width:45px; 
  67.  } 
  68.  </style> 
  69.      <script type="text/javascript" language="javascript" src="jquery.js"></script> 
  70.      <script type="text/javascript" language="javascript"
  71.   
  72.  var jqVirtualTable = { 
  73.   data:[],   //数据源,需要提供 
  74.   page: 0,   //当前页码 
  75.   pageRows: 30,   //每页行数,需要提供 
  76.   headerHeight: 21,  //th行高(pixel),需要提供 
  77.   rowHeight: 27,   //td行高(pixel),需要提供 
  78.   colCount: 0,   //列数 
  79.   controls: {   //缓存控件 
  80.    tabObj: null,  //数据table 
  81.    wrapObj: null  //外层包裹的div 
  82.   }, 
  83.    
  84.   //初始化 
  85.   init: function(tableId, wrapperId){ 
  86.    //缓存主要控件 
  87.    this.controls.tabObj = $("#" + tableId); 
  88.    this.controls.wrapObj = $("#" + wrapperId); 
  89.     
  90.    //数据计算 
  91.    this.colCount = this.controls.tabObj.find("tr:eq(0)").find("th").length; 
  92.     
  93.    //挂接事件 
  94.    this.controls.wrapObj.scroll($.proxy(this.scrollhandler, this)); 
  95.    this.controls.tabObj.click($.proxy(this.clickhandler, this)); 
  96.  
  97.    //绘制表格 
  98.    this.render(); 
  99.   }, 
  100.    
  101.   //绘制表格 
  102.   render: function(){ 
  103.    this.controls.tabObj.find("tr:gt(0)").remove(); 
  104.  
  105.    var startIndex = this.page == 0? 0 : ((this.page - 1) * this.pageRows); 
  106.    var endIndex = startIndex + 3 * this.pageRows; 
  107.    if(endIndex > this.data.length) 
  108.     endIndex = this.data.length; 
  109.      
  110.    var topH = startIndex * this.rowHeight; 
  111.    var bottomH = (this.data.length - (endIndex - startIndex + 1)) * this.rowHeight - topH; 
  112.    if(bottomH < 0)  
  113.     bottomH = 0; 
  114.  
  115.    var html = []; 
  116.    html.push("<tr><td colspan='" + this.colCount + "' style='padding:0;height:" + topH + "px'></td></tr>"); 
  117.    html.push(this.getRowsHtml(startIndex, endIndex)); 
  118.    html.push("<tr><td colspan='" + this.colCount + "' style='padding:0;height:" + bottomH + "px'></td></tr>"); 
  119.     
  120.    $(html.join('')).appendTo(this.controls.tabObj.find("tbody")); 
  121.   }, 
  122.    
  123.   //生成给定区间行的html,需要重写 
  124.   getRowsHtml: function(start, end){ 
  125.    var html = []; 
  126.    for(var i = start;i < end;++i){ 
  127.     var item = this.data[i]; 
  128.     html.push("<tr><td>" + item[0] + ". " + item[1][0] + "(" + item[2]+ ")</td>"); 
  129.     html.push("<td>" + item[1][1] + "</td>"); 
  130.     html.push("<td>" + item[3] + "</td>"); 
  131.     html.push("<td><button class='btn' pid='" + item[0] + "'>忽略</button></td></tr>"); 
  132.    } 
  133.     
  134.    return html.join(''); 
  135.   }, 
  136.    
  137.   //外层包裹div的scroll事件处理 
  138.   scrollhandler: function(){ 
  139.    $("#wrapperHead").scrollLeft(this.controls.wrapObj.scrollLeft()); 
  140.    //计算纵向滚动对应的页码,判断是否需要换页 
  141.    var scrollTop = this.controls.wrapObj.scrollTop(); 
  142.    var posPage = Math.floor((scrollTop + this.headerHeight) / (this.pageRows * this.rowHeight)); 
  143.    if(posPage != this.page){ 
  144.     this.page = posPage; 
  145.     this.render(); 
  146.     this.controls.wrapObj.focus(); 
  147.    } 
  148.   }, 
  149.    
  150.   //表格click事件处理,需要重写 
  151.   clickhandler: function(e){ 
  152.    var eleName = e.target.tagName.toLowerCase();; 
  153.    if(eleName != "button"
  154.     return
  155.      
  156.    var id = $(e.target).attr("pid"); 
  157.    alert("忽略id=" + id); 
  158.   } 
  159.  }; 
  160.  
  161.  $(function(){ 
  162.   //构造测试用数据 
  163.   var fileNameArray = [ 
  164.     ["svch0st.dll""C:\\Windows\system32"],  
  165.     ["win.com""D:\\Program Files"], 
  166.     ["n0tepad.exe""C:\\"], 
  167.     ["twunk32.exe""C:\\windows"], 
  168.     ["regedit.exe""C:\\Winnt\\system32\\drivers"], 
  169.     ["hh.exe""F:\\Test"]]; 
  170.   var virusNameArray = ["灰鸽子""尼姆达""熊猫烧香""蠕虫"]; 
  171.   var handleState = ["已隔离""不处理""未能隔离"]; 
  172.    
  173.   for(var i = 0;i < 500;++i){ 
  174.    jqVirtualTable.data.push([ 
  175.     i+1,  
  176.     fileNameArray[Math.floor(Math.random() * 6)],  
  177.     virusNameArray[Math.floor(Math.random() * 4)], 
  178.     handleState[Math.floor(Math.random() * 3)] 
  179.    ]); 
  180.   } 
  181.    
  182.   //初始化 
  183.   jqVirtualTable.pageRows = 25; 
  184.   jqVirtualTable.init("data""wrapperBody"); 
  185.    
  186.   /* 
  187.   //测试追加数据 
  188.   window.setInterval(function(){ 
  189.    for(var i = 0;i < 100;++i){ 
  190.     jqVirtualTable.data.push([ 
  191.      i+1,  
  192.      fileNameArray[Math.floor(Math.random() * 6)],  
  193.      virusNameArray[Math.floor(Math.random() * 4)], 
  194.      handleState[Math.floor(Math.random() * 3)] 
  195.     ]); 
  196.    } 
  197.     
  198.    jqVirtualTable.render(); 
  199.   }, 5000); 
  200.   */ 
  201.  }); 
  202.   
  203.  </script> 
  204. </head>  
  205. <body> 
  206.  
  207. <div id="wrapperHead"
  208.  <table> 
  209.   <tr class="h"
  210.    <th width="30%">文件名</th> 
  211.    <th>路径</th> 
  212.    <th width="20%">结果</th> 
  213.    <th width="160">操作</th> 
  214.   </tr> 
  215.  </table> 
  216. </div> 
  217. <div id="wrapperBody"
  218.  <table id="data"
  219.   <tr class="h"
  220.    <th width="30%">文件名</th> 
  221.    <th>路径</th> 
  222.    <th width="20%">结果</th> 
  223.    <th width="160">操作</th> 
  224.   </tr> 
  225.  </table> 
  226. </div> 
  227.  
  228. </body>  
  229. </html> 

你可能感兴趣的:(职场,休闲,虚拟表格)