本文介绍如何使用原生JavaScript操作DOM来动态刷新表格数据,替代第三方插件。针对IE浏览器中插件导致内存累积崩溃的问题,提供了一套轻量级解决方案。通过解析JSON数据,利用insertRow和insertCell方法动态增删表格行与单元格,并配合deleteRow方法清理旧数据。该方法无需复杂逻辑,能有效避免内存溢出,适用于后台推送或Ajax请求的实时数据展示场景。
动态表格数据刷新背景与问题
在实时监控系统中,常需将后台推送的数据以表格形式动态展示。
虽然存在多种插件可实现此功能,但在IE浏览器中使用时,发现动态更新数据会导致内存持续累积,最终引发浏览器崩溃。
使用第三方插件虽功能丰富且效果较好,但依赖的JS文件和复杂逻辑使得问题排查与修复变得极为困难。
鉴于研究插件成本较高,直接手工编写原生代码成为更务实的选择。尽管缺乏额外特效,但实现动态表格数据刷新完全满足实际需求。
原生JS实现动态表格代码示例
以下为完整代码示例,将其嵌入HTML文件即可直接查看运行效果。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>
<style type="text/css">
.table0 {
font-family: "宋体";
font-size: 14px;
width: 400px;
border-top-width: 1px;
border-top-style: solid;
border-top-color: #c4cdd4;
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: #c4cdd4;
border-right-width: 1px;
border-right-style: solid;
border-right-color: #c4cdd4;
border-left-width: 1px;
border-left-style: solid;
border-left-color: #c4cdd4;
}
.table0 tr {
height : 25px;
padding-left:5px;
text-align: left;
}
.table0 th {
color: #4c7c9b;
font-weight: normal;
background-color: #f1f1f1;
height: 25px;
border-right-width: 1px;
border-right-style: solid;
border-right-color: #c4cdd4;
}
.table0 td {
border-right-width: 1px;
border-right-style: solid;
border-right-color: #c4cdd4;
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: #c4cdd4;
}
</style>
<script language="javascript" type="text/javascript">
var istt = false;
var values = "";
function callback(){
if(istt){
values = "[{'a':1,'b':'1','c':'1','d':'1'},{'a':2,'b':'2','c':'2','d':'2'},{'a':3,'b':'3','c':'3','d':'3'},{'a':4,'b':'4','c':'4','d':'4'}]";
istt=false;
}else{
values = "[{'a':10,'b':'10','c':'10','d':'10'},{'a':20,'b':'20','c':'20','d':'20'},{'a':30,'b':'30','c':'30','d':'30'},{'a':40,'b':'40','c':'40','d':'40'}]";
istt=true;
}
if(null!=values&&''!=values){
fnDeleteXLRow(); // 清除除标题外所有行
var objs=eval(values); // 解析JSON
for(var i=0;i<objs.length;i++){ // 循环对象
var u = objs[i];
var tab=document.getElementById("proc"); // 获得表格
var rows=tab.rows; // 表格ROW对象
var row1=tab.insertRow(rows.length); // 插入一行rows是一个数组,代表没一行,索引从0开始
row1.insertCell(0).innerHTML=" "+u.a; // insertCell插入列,从0开始
row1.insertCell(1).innerHTML=" "+u.b;
row1.insertCell(2).innerHTML=" "+u.c;
row1.insertCell(3).innerHTML=" "+u.d;
}
}
// 更新时间的改变
document.getElementById("endTime").value=curDateTime();
// 垃圾回收
CollectGarbage();
// 产生回调
setTimeout(callback, 1000);
}
// 删除所有行,不删除标题行
function fnDeleteXLRow(){
var table = document.getElementById('proc');
var rowCount = table.rows.length; // 获得一共多少行,因为不删除标题,所以索引从 1 开始
for(var i=1;i<rowCount;i++){
table.deleteRow(1); // 因为删除一行以后下面的行会顶上来,所以一直删除第一行即可
}
}
// 获得当前时间
function curDateTime(){
var d = new Date();
var year = d.getYear();
var month = d.getMonth()+1;
var date = d.getDate();
var day = d.getDay();
var hours = d.getHours();
var minutes = d.getMinutes();
var seconds = d.getSeconds();
var ms = d.getMilliseconds();
var curDateTime= year;
if(month>9)
curDateTime = curDateTime +"-"+month;
else
curDateTime = curDateTime +"-0"+month;
if(date>9)
curDateTime = curDateTime +"-"+date;
else
curDateTime = curDateTime +"-0"+date;
if(hours>9)
curDateTime = curDateTime +" "+hours;
else
curDateTime = curDateTime +" 0"+hours;
if(minutes>9)
curDateTime = curDateTime +":"+minutes;
else
curDateTime = curDateTime +":0"+minutes;
if(seconds>9)
curDateTime = curDateTime +":"+seconds;
else
curDateTime = curDateTime +":0"+seconds;
return curDateTime;
}
setTimeout(callback, 1000);
</script>
</head>
<body>
<div id="table_div" align="left">
<font size="2px"><b>最后更新时间:</b></font><input type="text" id="endTime" value="00-00-00 00:00:00" readonly="readonly">
<br>
<table id="proc" width="98%" border="0" cellspacing="0" cellpadding="0" class="table0">
<tr>
<th> <b>A</b></th>
<th> <b>B</b></th>
<th> <b>C</b></th>
<th> <b>D</b></th>
</tr>
</table>
</div>
</body>
</html>
运行效果如下所示。

演示数据中,数值会在个位数与十位数之间频繁变化,以体现动态刷新的实时性。
DOM操作实现原理与步骤
下面简要说明实现原理与步骤。
数据来源可以是实时推送或Ajax请求,核心在于解析JSON字符串。
解析JSON后,遍历对象数组。每次循环插入一行,并根据对象属性在行中创建单元格及填充内容。如需美化,可在此过程中设置行或单元格的样式。
每次插入新数据前,需先清除除标题行以外的所有现有行,以确保表格内容同步更新。
清除旧行的具体方法如下。
// 删除所有行,不删除标题行
function fnDeleteXLRow(){
var table = document.getElementById('proc');
var rowCount = table.rows.length; // 获得一共多少行,因为不删除标题,所以索引从 1 开始
for(var i=1;i<rowCount;i++){
table.deleteRow(1); // 因为删除一行以后下面的行会顶上来,所以一直删除第一行即可
}
}
首先获取表格总行数,由于保留标题行,循环索引从1开始。每次删除索引为1的行,因为删除后后续行会自动上移填补空位,这与Excel中的行删除逻辑一致。
遍历对象以动态增加行和列的代码实现如下。
for(var i=0;i<objs.length;i++){ // 循环对象
var u = objs[i];
var tab=document.getElementById("proc"); // 获得表格
var rows=tab.rows; // 表格ROW对象
var row1=tab.insertRow(rows.length); // 插入一行rows是一个数组,代表没一行,索引从0开始
row1.insertCell(0).innerHTML=" "+u.a; // insertCell插入列,从0开始
row1.insertCell(1).innerHTML=" "+u.b;
row1.insertCell(2).innerHTML=" "+u.c;
row1.insertCell(3).innerHTML=" "+u.d;
}
此外,还可以通过以下方式指定特定行或列的样式。
var row1cell0=row1.insertCell(0); // 指定列的样式 row1cell0.className="m_td1";
虽然可以单独设置样式,但通常建议为表格定义统一的CSS类,并在该类中统一处理样式,以保持代码整洁。
<table id="proc" width="98%" border="0" cellspacing="0" cellpadding="0" class="table0">
对应的CSS样式定义如下。
<style type="text/css">
.table0 {
font-family: "宋体";
font-size: 14px;
width: 400px;
border-top-width: 1px;
border-top-style: solid;
border-top-color: #c4cdd4;
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: #c4cdd4;
border-right-width: 1px;
border-right-style: solid;
border-right-color: #c4cdd4;
border-left-width: 1px;
border-left-style: solid;
border-left-color: #c4cdd4;
}
.table0 tr {
height : 25px;
padding-left:5px;
text-align: left;
}
.table0 th {
color: #4c7c9b;
font-weight: normal;
background-color: #f1f1f1;
height: 25px;
border-right-width: 1px;
border-right-style: solid;
border-right-color: #c4cdd4;
}
.table0 td {
border-right-width: 1px;
border-right-style: solid;
border-right-color: #c4cdd4;
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: #c4cdd4;
}
</style>
该样式仅作用于当前指定的表格,避免影响页面其他元素。
以上即为利用原生JS实现动态表格数据刷新的完整方案,希望对相关开发工作有所帮助。