用HTC做的客户端表格分页和点列头排序

本文介绍了一种使用JS实现的希尔排序算法,并应用于表格数据的分页展示中,通过具体实例代码展示了如何提高分页绘制效率,同时探讨了在大量数据处理时存在的性能瓶颈及可能的优化方向。

排序算法用的希尔。进入页面的时候,会先处理表格,将表格中的所有Row都放在了一个数组里面备用,然后删除表格中的行,只绘制本页面需要的Row。每次分页也是先删除本页的数据,然后只绘制本页面需要的数据。这样提高了分页绘制的效率,但是如果数据量太大,比如1万的时候,页面初始化的时候就不是很爽。呵呵

感觉js的效率太低,1000条数据的排序,用希尔竟然1~2秒的时间。不知道哪位达人有好的方法作。

这两天抽空做一个XML的,效率应该会高些。

-------------------- 以下是HTC文件----------------------

<public:attach event="ondocumentready" onevent="init()" />
<public:property name="BatchSize" />
<public:property name="PageSize" />
<public:property name="OverColor" />
<public:property name="SelectColor" />
<public:property name="DefualtColor" />

<script language="JScript">
Object.prototype.Clone = function ()
{
    var newObj = new Object();
    for(elements in this)
    {
        newObj[elements] = this[elements];
    }
    return newObj;
}


var lastclick = -1;
var CurrentBatchIndex=1;
var CurrentPageIndex=1;
var RowsCount=0;
var ColsCount=0;
var pagingCell;
var TmpTable;
var pagingRow;

var clickbakRowIndex = -1;


var Rows;
var Cells;

var CurrentOrderField;
var CurrentOrder;

function ShellSort(arr, orderIndex)
{ //插入排序->希儿排序
    var st = new Date();
    var increment = arr.length;
    do
    {
        increment = (increment/3|0) + 1;
        arr = ShellPass(arr, increment, orderIndex);
    }
    while (increment > 1)

    status = (new Date() - st) + ' ms';
    return arr;
}

function ShellPass(arr, d, orderIndex)
{ //希儿排序分段执行函数
    var temp, j;
    if(CurrentOrder=="DESC")
    {
        for(var i=d; i<arr.length; i++)
        {
            if((arr[i].cells[orderIndex].innerText) > (arr[i-d].cells[orderIndex].innerText))
            {
                temp = arr[i]; j = i-d;
                do
                {
                    arr[j+d] = arr[j];
                    j = j-d;
                }
                while (j>-1 && (temp.cells[orderIndex].innerText) > (arr[j].cells[orderIndex].innerText));
                    arr[j+d] = temp;
            }//endif
        }
    }
    else
    {
        for(var i=d; i<arr.length; i++)
        {
            if((arr[i].cells[orderIndex].innerText) < (arr[i-d].cells[orderIndex].innerText))
            {
                temp = arr[i]; j = i-d;
                do
                {
                    arr[j+d] = arr[j];
                    j = j-d;
                }
                while (j>-1 && (temp.cells[orderIndex].innerText) < (arr[j].cells[orderIndex].innerText));
                    arr[j+d] = temp;
            }//endif
        }
    }
    return arr;
}

function init()
{
    if(OverColor == null) OverColor = "#E5F1FF";
    if(DefualtColor == null) DefualtColor="#ffffff";
    if(SelectColor == null) SelectColor="#FFEFCE";
    if(PageSize == null)PageSize=5;
    if(BatchSize == null)BatchSize=5;
 
    element.attachEvent("onmouseover",OverThis);
    element.attachEvent("onmouseout",OutThis);
    element.attachEvent("onclick",ClickThis);
   
    RowsCount = element.rows.length-1;
    if(RowsCount>0)
        ColsCount = element.rows[0].cells.length;
       
    ReadTableToArrayList();
   
    element.rows[0].runtimeStyle.cursor = "hand";
    for(var i=0;i<ColsCount;i++)
    {
        element.cells[i].attachEvent("onclick",SortTable)
    }
    DrawPageRow();
}

function SortTable()
{    
    if(event.srcElement != element && event.srcElement.tagName!="SPAN")
    {
        if(CurrentOrderField!=event.srcElement.innerText
                && (CurrentOrderField+"5")!=event.srcElement.innerText
                && (CurrentOrderField+"6")!=event.srcElement.innerText)
            {CurrentOrder="";}
        for(var i=0;i<ColsCount;i++)
        {
            if(element.rows[0].cells[i].innerHTML.indexOf("<SPAN class=arrow>")>=0)
            {
            //element.rows[0].cells[i].innerHTML.substring(0,element.rows[0].cells[i].innerHTML.indexOf('<SPAN class=arrow>'))
                element.rows[0].cells[i].innerHTML=element.rows[0].cells[i].innerHTML.replace("<SPAN class=arrow>5</SPAN>","");
                element.rows[0].cells[i].innerHTML=element.rows[0].cells[i].innerHTML.replace("<SPAN class=arrow>6</SPAN>","");
            }
        }
        for(var i=0;i<ColsCount;i++)
        {
            if(element.rows[0].cells[i].innerText == event.srcElement.innerText)
            {
                CurrentOrderField=event.srcElement.innerText;
                if(CurrentOrder=="ASC")
                {
                    CurrentOrder="DESC";
                    event.srcElement.innerHTML+="<span class='arrow'>6</span>";
                }
                else
                {
                    CurrentOrder="ASC";
                    event.srcElement.innerHTML+="<span class='arrow'>5</span>";
                }
                Rows=ShellSort(Rows,i);
                break;
            }
        }
    }
   
    ReDrawTable();
    DrawPageRow();
}

function ReadTableToArrayList()
{
    if(null==TmpTable)
    {
        var t = window.document.getElementById("GridView1");
        var TmpTable = t.cloneNode(true)
    }
    if(RowsCount>0 && ColsCount>0)
    {
        Rows=new Array(RowsCount);
        for(var i=0;i<RowsCount;i++)
        {
            Rows[i]=TmpTable.rows[i+1];
        }
        pagingRow=TmpTable.rows[TmpTable.rows.length-1];
    }
    else
    {
        Rows=null;
    }
   
    ReDrawTable();
}

function ReDrawTable()
{
    for(var i=element.rows.length-1;i>0;i--)
    {
        element.deleteRow(i);
    }
   
    var TRs=Rows.Clone();
    for(var i=1;i<=PageSize;i++)
    {
        foRow = element.insertRow();
        if((CurrentPageIndex-1)*PageSize-(-i)<Rows.length)
        {
            for(var j=0;j<TRs[(CurrentPageIndex-1)*PageSize-(-i)].cells.length;j++)
            {
                c=foRow.insertCell();
                c.innerHTML=TRs[(CurrentPageIndex-1)*PageSize-(-i)].cells[j].innerHTML;
            }
        }
    }
    //DrawPageRow();
    //onPaging();
//    if(null!=pagingRow)
//    {
//        foRow=element.insertRow();
//        c=foRow.insertCell();
//        c.innerHTML=pagingRow.cells[0].innerHTML;
//        c.colSpan=ColsCount;
//        c.align="right";
//    }
}

function ClickThis()
{
    if(event.srcElement != element)
    {
         var currentRow = getTR();
         if(currentRow!=null && currentRow.rowIndex != 0  && currentRow.rowIndex != (element.rows.length-1))
         {
             if(clickbakRowIndex != -1)
             {
                 element.rows[clickbakRowIndex].runtimeStyle.backgroundColor = ''
             }
             clickbakRowIndex = currentRow.rowIndex;
             currentRow.runtimeStyle.backgroundColor = SelectColor;
         }
    }
}

function getTR()
{
    var obj = event.srcElement;
    if(obj == element) return null;
    while (obj.tagName != "TR")
    {
     obj = obj.parentElement;
        if(obj == null) return null;
    }
 return obj;
}

function OverThis()
{
    if(event.srcElement != element)
    {
     var currentRow = getTR();
     if(currentRow == null) return;
     if(currentRow.rowIndex != 0  && currentRow.rowIndex != (element.rows.length-1) && currentRow.rowIndex != clickbakRowIndex)
     {
         currentRow.runtimeStyle.backgroundColor = OverColor;
     }
    }
}

function OutThis()
{
    if(event.srcElement != element)
    {
     var currentRow = getTR();
     if(currentRow == null) return;
     if(currentRow.rowIndex != 0  && currentRow.rowIndex != (element.rows.length-1) && currentRow.rowIndex != clickbakRowIndex)
     {
         currentRow.runtimeStyle.backgroundColor = DefualtColor;
     }
    }
}

function onBatching()
{
    var Obj = event.srcElement;
    if(Obj.id.toLowerCase() == "nextbatch")
    {
        CurrentBatchIndex++;
        CurrentPageIndex = (CurrentBatchIndex - 1) * BatchSize + 1;
        ReDrawTable();
        DrawPageRow();
    }
    else if(Obj.id.toLowerCase() == "prebatch")
    {
        CurrentBatchIndex--;
        CurrentPageIndex = (CurrentBatchIndex - 1) * BatchSize + 5;
        ReDrawTable();
        DrawPageRow();
    }
}

function onPaging()
{
    var obj = event.srcElement;
    CurrentPageIndex = new Number(obj.innerText)
  
    ReDrawTable();
    DrawPageRow();
}

function DrawPageRow()
{
    if(element.rows.length > (PageSize+1))
    {
        element.deleteRow(element.rows.length-1);
    }


    var pageNumber = Math.ceil(RowsCount/PageSize);
    pagingRow = element.insertRow();
   
    pagingCell = pagingRow.insertCell();
    pagingCell.colSpan = element.rows[0].cells.length;
    pagingCell.align = "right";
       
    var preBatch = document.createElement("span");
   
    if(CurrentBatchIndex > 1)
    {
        preBatch.innerHTML = "...";
        preBatch.id = 'PreBatch';
        preBatch.attachEvent('onclick',onBatching);
        preBatch.style.cursor = 'hand';
        preBatch.style.textDecoration = 'underline';
    }
    pagingCell.insertAdjacentElement('beforeEnd',preBatch);

    var blank = document.createElement("span");
    blank.innerHTML = "&nbsp;&nbsp;";
    pagingCell.insertAdjacentElement('beforeEnd',blank);
   
    var pageIndex;
    for(var i = 0;i<BatchSize;i++)
    {
        if(((CurrentBatchIndex-1)*BatchSize-(-i)) * PageSize < RowsCount)
        {
            pageIndex = document.createElement("span");
       
            pageIndex.innerHTML = ((CurrentBatchIndex-1)*BatchSize-(-i)-(-1)).toString();
            if(pageIndex.innerHTML.toString() != CurrentPageIndex.toString())
            {
                pageIndex.style.cursor = 'hand';
                pageIndex.id = 'pageNumber';
                pageIndex.myPageIndex = (CurrentPageIndex-(-i)).toString();
                pageIndex.attachEvent('onclick',onPaging);
                pageIndex.style.textDecoration = 'underline';
            }
            pagingCell.insertAdjacentElement('beforeEnd',pageIndex);

            blank = document.createElement("span");
            blank.innerHTML = "&nbsp;&nbsp;";
            pagingCell.insertAdjacentElement('beforeEnd',blank);
        }
    }
   
    //if(CurrentPageIndex-(-BatchSize) < RowsCount)
    if((CurrentBatchIndex * BatchSize) * PageSize < RowsCount)
    {
        var nextBatch = document.createElement("span");

        nextBatch.innerHTML = "...";
        nextBatch.id = 'NextBatch';
        nextBatch.attachEvent('onclick',onBatching);
        nextBatch.style.textDecoration = 'underline';
        nextBatch.style.cursor = 'hand';
        pagingCell.insertAdjacentElement('beforeEnd',nextBatch);
    }
}

String.prototype.trim = function(){return this.replace(/(^/s*)|(/s*$)/g,'');}
</script>

 

 

--------------------测试页面的代码----------------------

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
  // 计算数据,完全可以从数据看取得
  ICollection CreateDataSource( )
  {
    System.Data.DataTable dt = new System.Data.DataTable();
    System.Data.DataRow dr;
    dt.Columns.Add(new System.Data.DataColumn("AAA", typeof(System.String)));
    dt.Columns.Add(new System.Data.DataColumn("BBB", typeof(System.String)));
    dt.Columns.Add(new System.Data.DataColumn("CCC", typeof(System.Decimal)));
    dt.Columns.Add(new System.Data.DataColumn("DDD", typeof(System.Decimal)));
    dt.Columns.Add(new System.Data.DataColumn("EEE", typeof(System.Decimal)));
    dt.Columns.Add(new System.Data.DataColumn("FFF", typeof(System.Decimal)));

    for (int i = 0; i < 1000; i++)
    {
      System.Random rd = new System.Random(Environment.TickCount * i); ;
      dr = dt.NewRow();
      dr[0] = "ZZZ" + i.ToString();
      dr[1] = "TEST" + i.ToString();
      dr[2] = System.Math.Round(rd.NextDouble() * 100, 2);
      dr[3] = System.Math.Round(rd.NextDouble() * 100, 2);
      dr[4] = System.Math.Round(rd.NextDouble() * 100, 2);
      dr[5] = System.Math.Round(rd.NextDouble() * 100, 2);
      dt.Rows.Add(dr);
    }
    System.Data.DataView dv = new System.Data.DataView(dt);
    return dv;
  }

  protected void Page_Load( object sender, EventArgs e )
  {
    if (!IsPostBack)
    {
      GridView1.Attributes.Add("style", "table-layout:fixed");
      GridView1.DataSource = CreateDataSource();
      GridView1.DataBind();
    }
  }
 
</script>

<script type="text/javascript">
function s()
{
 var t = document.getElementById("<%=GridView1.ClientID%>");
 var t2 = t.cloneNode(true)
 for(i = t2.rows.length - 1;i > 0;i--)
 t2.deleteRow(i) 
 t.deleteRow(0) 
 a.appendChild(t2)
}
//window.onload = s
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>TestNBTable</title>
  <style type="text/css">
  .TableA
  {
    behavior: url(/Test/AAA.htc);
  }
  .arrow   {  
    FONT-WEIGHT:   normal;   FONT-FAMILY:   Marlett;   LETTER-SPACING:   -3px;   POSITION:   relative;   TOP:   2px  
  }  
  </style>
</head>
<body>
  <form id="Form1" runat="server">
  <input name="Shell1" id="Shell1" type="text" size="100" value="6,g,v,u,f,p,o,i,a,t,j"/>
  <input name="Shell2" id="Shell2" type="text" size="100" value="8,g,v,u,f,p,o,i,a,t,j"/>
  <input name="Shell3" id="Shell3" type="text" size="100" value="1,g,v,u,f,p,o,i,a,t,j"/>
  <input name="Shell4" id="Shell4" type="text" size="100" value="4,g,v,u,f,p,o,i,a,t,j"/>
  <input name="Shell5" id="Shell5" type="text" size="100" value="2,g,v,u,f,p,o,i,a,t,j"/>
  <input name="Shell6" id="Shell6" type="text" size="100" value="0,g,v,u,f,p,o,i,a,t,j"/>
  <table><tr><td class="arrow">5</td></tr></table>
  <asp:GridView ID="GridView1" runat="server" Font-Size="12px" BackColor="#FFFFFF"
              GridLines="Both" CellPadding="4" Width="560" CssClass="TableA">
              <HeaderStyle BackColor="#EDEDED" Height="26px" />
                <SelectedRowStyle BackColor="#FFFFC0" />
            </asp:GridView>
    <table>
      <tr>
        <td>
          <div id="a">
          </div>
          <div style="overflow-y: scroll; height: 100%">
           
          </div>
        </td>
      </tr>
    </table>
  </form>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值