在网页中用table加载大量数据是件痛苦的事,效率太低了,对内存的占用也太大了。联想到C#中用到的DataGridView的虚拟模式,试着在网页中用html+js实现了一个,没仔细测,通用性封装也不好,给大家抛块砖而已。
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <title>表格虚拟模式</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <style type="text/css">
- * {
- font-size:12px;
- padding:0;
- margin:0;
- }
- html,body{
- height:100%;
- }
- #wrapperHead{
- width:583px;
- position:absolute;
- top:21px;
- left:41px;
- z-index:100;
- overflow:hidden;
- }
- #wrapperBody{
- width:600px;
- height:90%;
- overflow-y:auto;
- overflow-x:auto;
- border:solid 1px black;
- position:absolute;
- top:20px;
- left:40px;
- }
- table{
- width:700px;
- border-collapse:collapse;
- table-layout:fixed;
- }
- tr:hover{
- background-color:#eee;
- }
- td{
- padding:3px;
- white-space:nowrap;
- overflow:hidden;
- text-overflow:ellipsis;
- cursor:default;
- height:21px;
- }
- th{
- padding:3px;
- white-space:nowrap;
- overflow:hidden;
- text-overflow:ellipsis;
- cursor:default;
- background-color:#06c;
- color:white;
- border-left:solid 1px darkgray;
- height:15px;
- }
- #msg{
- position:absolute;
- top:5px;
- left:10px;
- }
- .btn{
- width:45px;
- }
- </style>
- <script type="text/javascript" language="javascript" src="jquery.js"></script>
- <script type="text/javascript" language="javascript">
- var jqVirtualTable = {
- data:[], //数据源,需要提供
- page: 0, //当前页码
- pageRows: 30, //每页行数,需要提供
- headerHeight: 21, //th行高(pixel),需要提供
- rowHeight: 27, //td行高(pixel),需要提供
- colCount: 0, //列数
- controls: { //缓存控件
- tabObj: null, //数据table
- wrapObj: null //外层包裹的div
- },
- //初始化
- init: function(tableId, wrapperId){
- //缓存主要控件
- this.controls.tabObj = $("#" + tableId);
- this.controls.wrapObj = $("#" + wrapperId);
- //数据计算
- this.colCount = this.controls.tabObj.find("tr:eq(0)").find("th").length;
- //挂接事件
- this.controls.wrapObj.scroll($.proxy(this.scrollhandler, this));
- this.controls.tabObj.click($.proxy(this.clickhandler, this));
- //绘制表格
- this.render();
- },
- //绘制表格
- render: function(){
- this.controls.tabObj.find("tr:gt(0)").remove();
- var startIndex = this.page == 0? 0 : ((this.page - 1) * this.pageRows);
- var endIndex = startIndex + 3 * this.pageRows;
- if(endIndex > this.data.length)
- endIndex = this.data.length;
- var topH = startIndex * this.rowHeight;
- var bottomH = (this.data.length - (endIndex - startIndex + 1)) * this.rowHeight - topH;
- if(bottomH < 0)
- bottomH = 0;
- var html = [];
- html.push("<tr><td colspan='" + this.colCount + "' style='padding:0;height:" + topH + "px'></td></tr>");
- html.push(this.getRowsHtml(startIndex, endIndex));
- html.push("<tr><td colspan='" + this.colCount + "' style='padding:0;height:" + bottomH + "px'></td></tr>");
- $(html.join('')).appendTo(this.controls.tabObj.find("tbody"));
- },
- //生成给定区间行的html,需要重写
- getRowsHtml: function(start, end){
- var html = [];
- for(var i = start;i < end;++i){
- var item = this.data[i];
- html.push("<tr><td>" + item[0] + ". " + item[1][0] + "(" + item[2]+ ")</td>");
- html.push("<td>" + item[1][1] + "</td>");
- html.push("<td>" + item[3] + "</td>");
- html.push("<td><button class='btn' pid='" + item[0] + "'>忽略</button></td></tr>");
- }
- return html.join('');
- },
- //外层包裹div的scroll事件处理
- scrollhandler: function(){
- $("#wrapperHead").scrollLeft(this.controls.wrapObj.scrollLeft());
- //计算纵向滚动对应的页码,判断是否需要换页
- var scrollTop = this.controls.wrapObj.scrollTop();
- var posPage = Math.floor((scrollTop + this.headerHeight) / (this.pageRows * this.rowHeight));
- if(posPage != this.page){
- this.page = posPage;
- this.render();
- this.controls.wrapObj.focus();
- }
- },
- //表格click事件处理,需要重写
- clickhandler: function(e){
- var eleName = e.target.tagName.toLowerCase();;
- if(eleName != "button")
- return;
- var id = $(e.target).attr("pid");
- alert("忽略id=" + id);
- }
- };
- $(function(){
- //构造测试用数据
- var fileNameArray = [
- ["svch0st.dll", "C:\\Windows\system32"],
- ["win.com", "D:\\Program Files"],
- ["n0tepad.exe", "C:\\"],
- ["twunk32.exe", "C:\\windows"],
- ["regedit.exe", "C:\\Winnt\\system32\\drivers"],
- ["hh.exe", "F:\\Test"]];
- var virusNameArray = ["灰鸽子", "尼姆达", "熊猫烧香", "蠕虫"];
- var handleState = ["已隔离", "不处理", "未能隔离"];
- for(var i = 0;i < 500;++i){
- jqVirtualTable.data.push([
- i+1,
- fileNameArray[Math.floor(Math.random() * 6)],
- virusNameArray[Math.floor(Math.random() * 4)],
- handleState[Math.floor(Math.random() * 3)]
- ]);
- }
- //初始化
- jqVirtualTable.pageRows = 25;
- jqVirtualTable.init("data", "wrapperBody");
- /*
- //测试追加数据
- window.setInterval(function(){
- for(var i = 0;i < 100;++i){
- jqVirtualTable.data.push([
- i+1,
- fileNameArray[Math.floor(Math.random() * 6)],
- virusNameArray[Math.floor(Math.random() * 4)],
- handleState[Math.floor(Math.random() * 3)]
- ]);
- }
- jqVirtualTable.render();
- }, 5000);
- */
- });
- </script>
- </head>
- <body>
- <div id="wrapperHead">
- <table>
- <tr class="h">
- <th width="30%">文件名</th>
- <th>路径</th>
- <th width="20%">结果</th>
- <th width="160">操作</th>
- </tr>
- </table>
- </div>
- <div id="wrapperBody">
- <table id="data">
- <tr class="h">
- <th width="30%">文件名</th>
- <th>路径</th>
- <th width="20%">结果</th>
- <th width="160">操作</th>
- </tr>
- </table>
- </div>
- </body>
- </html>
本文转自 BoyTNT 51CTO博客,原文链接:http://blog.51cto.com/boytnt/774888
,如需转载请自行联系原作者