JavaScript表格排序新法
不知大家对精华区的表格排序终极优化是否还有记忆,当时讨论的结果曾以为是最快的JS排序了,实则不然,按前段时间我发的DHTML性能提升帖(转译)所讲到的,DOM效率某些情况下并不如DHTML,比如一次写入大量数据时,DOM频繁创建添加反而更慢,所以可以对排序算法作修改:
<table id="downloadList" border="1" width="100%" onclick="sortTable()">
<tr>
<td>AddCommonInfo.mxp</td>
<td>MXP File</td>
<td>2614</td>
<td>2002-12-30 16:45:22,Fri</td>
</tr>
<tr>
<td>addtemplateparam.mxp</td>
<td>MXP File</td>
<td>3100</td>
<td>2002-12-5 13:28:24,Sun</td>
</tr>
</table>
<script>
var curObj;
function sortTable() {
var start=new Date();
var i;
var theRows=new Array();
for(i=0;i<downloadList.rows.length;i++) {
theRows[i]=new Array(downloadList.rows[i].cells[0].innerText.toLowerCase(),downloadList.rows[i].outerHTML);
}
theRows.sort(sortRows);
var str=''
for(i=0;i<theRows.length;i++) {
str+=theRows[i][1];
}
downloadList.outerHTML='<table id=downloadList border="1" width="100%">'+str+'</table>'
curObj=null;
alert(new Date()-start)
return ;
}
function sortRows(x,y) {
if(x[0]>y[0]) return -1;
else if(x[0]<y[0]) return 1;
else return 0;
}
</script>
<tr>
<td>AddCommonInfo.mxp</td>
<td>MXP File</td>
<td>2614</td>
<td>2002-12-30 16:45:22,Fri</td>
</tr>
<tr>
<td>addtemplateparam.mxp</td>
<td>MXP File</td>
<td>3100</td>
<td>2002-12-5 13:28:24,Sun</td>
</tr>
</table>
<script>
var curObj;
function sortTable() {
var start=new Date();
var i;
var theRows=new Array();
for(i=0;i<downloadList.rows.length;i++) {
theRows[i]=new Array(downloadList.rows[i].cells[0].innerText.toLowerCase(),downloadList.rows[i].outerHTML);
}
theRows.sort(sortRows);
var str=''
for(i=0;i<theRows.length;i++) {
str+=theRows[i][1];
}
downloadList.outerHTML='<table id=downloadList border="1" width="100%">'+str+'</table>'
curObj=null;
alert(new Date()-start)
return ;
}
function sortRows(x,y) {
if(x[0]>y[0]) return -1;
else if(x[0]<y[0]) return 1;
else return 0;
}
</script>
注意测试时将记录条数增加到500条以上,推荐1000条
我测试结果是平均1322ms左右
但这样就是最快的吗?非也,且看以下xml+xslt+js例子,能把时间缩短到721ms左右
需要准备三个文件
注意测试时将记录条数增加到500条以上,推荐1000条
我测试结果是平均1322ms左右
但这样就是最快的吗?非也,且看以下xml+xslt+js例子,能把时间缩短到721ms左右
需要准备三个文件
1. sort.xml文件 ---节省版面起见,这里只罗列两条记录
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<record>
<info>AddCommonInfo.mxp</info>
<info>MXP File</info>
<info>2614</info>
<info>2002-12-30 16:45:22,Fri</info>
</record>
<record>
<info>addtemplateparam.mxp</info>
<info>MXP File</info>
<info>3100</info>
<info>2002-12-5 13:28:24,Sun</info>
</record>
</root>
<root>
<record>
<info>AddCommonInfo.mxp</info>
<info>MXP File</info>
<info>2614</info>
<info>2002-12-30 16:45:22,Fri</info>
</record>
<record>
<info>addtemplateparam.mxp</info>
<info>MXP File</info>
<info>3100</info>
<info>2002-12-5 13:28:24,Sun</info>
</record>
</root>
2. sort.xsl 文件
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" version="1.0">
<xsl:template match="root">
<table border="1" width="100%">
<xsl:for-each select="record">
<tr>
<xsl:for-each select="info">
<td>
<xsl:value-of select="text()" />
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" version="1.0">
<xsl:template match="root">
<table border="1" width="100%">
<xsl:for-each select="record">
<tr>
<xsl:for-each select="info">
<td>
<xsl:value-of select="text()" />
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
3. default.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<script>
function safeLoadXML(xmlObj,url,func)
{
xmlObj.async = true;
xmlObj.resolveExternals = false;
xmlObj.onreadystatechange = function()
{
if(xmlObj.readyState==4 && xmlObj.parseError==0) { func(xmlObj); }
}
xmlObj.load(url);
}
function transformXML(xmlObj,xslObj)
{
var returnValue = xmlObj.transformNode(xslObj);
return returnValue;
}
var xmlDoc = new ActiveXObject("Msxml.DOMDocument");
var xslDoc = new ActiveXObject("Msxml.DOMDocument");
function init()
{
safeLoadXML(xmlDoc,'sort.xml',
function()
{
safeLoadXML(xslDoc,'sort.xsl',
function()
{
test.innerHTML = transformXML(xmlDoc.documentElement,xslDoc.documentElement); });
});
}
function sortIt()
{var start=new Date();
var temp = [];
for(var i=0;i<xmlDoc.documentElement.childNodes.length;i++)
{
temp[temp.length] = [xmlDoc.documentElement.childNodes[i].firstChild.firstChild.nodeValue,xmlDoc.documentElement.childNodes[i]]
}
temp.sort(sortFunc);
for(var i=0;i<temp.length;i++)
{
xmlDoc.documentElement.insertBefore(temp[i][1],xmlDoc.documentElement.firstChild)
}
test.innerHTML = transformXML(xmlDoc.documentElement,xslDoc.documentElement);
alert(new Date()-start);
}
function sortFunc(x,y)
{
if(x[0].toLowerCase()>y[0].toLowerCase()) return 1;
else if(x[0].toLowerCase()<y[0].toLowerCase()) return -1;
else return 0;
}
window.onload=init;
</script>
</HEAD>
<BODY>
<div id="test" onclick="sortIt()"></div>
</BODY>
</HTML>
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<script>
function safeLoadXML(xmlObj,url,func)
{
xmlObj.async = true;
xmlObj.resolveExternals = false;
xmlObj.onreadystatechange = function()
{
if(xmlObj.readyState==4 && xmlObj.parseError==0) { func(xmlObj); }
}
xmlObj.load(url);
}
function transformXML(xmlObj,xslObj)
{
var returnValue = xmlObj.transformNode(xslObj);
return returnValue;
}
var xmlDoc = new ActiveXObject("Msxml.DOMDocument");
var xslDoc = new ActiveXObject("Msxml.DOMDocument");
function init()
{
safeLoadXML(xmlDoc,'sort.xml',
function()
{
safeLoadXML(xslDoc,'sort.xsl',
function()
{
test.innerHTML = transformXML(xmlDoc.documentElement,xslDoc.documentElement); });
});
}
function sortIt()
{var start=new Date();
var temp = [];
for(var i=0;i<xmlDoc.documentElement.childNodes.length;i++)
{
temp[temp.length] = [xmlDoc.documentElement.childNodes[i].firstChild.firstChild.nodeValue,xmlDoc.documentElement.childNodes[i]]
}
temp.sort(sortFunc);
for(var i=0;i<temp.length;i++)
{
xmlDoc.documentElement.insertBefore(temp[i][1],xmlDoc.documentElement.firstChild)
}
test.innerHTML = transformXML(xmlDoc.documentElement,xslDoc.documentElement);
alert(new Date()-start);
}
function sortFunc(x,y)
{
if(x[0].toLowerCase()>y[0].toLowerCase()) return 1;
else if(x[0].toLowerCase()<y[0].toLowerCase()) return -1;
else return 0;
}
window.onload=init;
</script>
</HEAD>
<BODY>
<div id="test" onclick="sortIt()"></div>
</BODY>
</HTML>