当前位置:编程学习 > C#/ASP.NET >>

[HELP]GRIDVIEW的表头和列固定滚动,有性能问题,麻烦请修正

GRIDVIEW的表头和列固定滚动代码参照下面 IE6,IE7,IE8,FF测试OK
问题:GRIDVIEW的记录2000以上(目前500),由于js对table行列删除,显示速度慢,
cloneNode速度快,有没有好的方法代替deleteRow,deleteCell
※另:如果不删除多余的行和列,用left(-XXX)速度还可以,不过最好能删除
javascript:FixedGridViewHeaderItems中循环麻烦达人修正,thanks!

client:
<!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 runat="server">
    <title>Fix Header,Left Of GridView</title>
    <script  language ="javascript" type="text/javascript" >
        function FixedGridViewHeaderItems(gvID, fixedCellsCount) {
            try {
                var gvItems = document.getElementById(gvID);
                //header
                var tmpgvItems = gvItems.cloneNode(true);
                //left
                var tmpgvFixed = gvItems.cloneNode(true);
                
                for (i = gvItems.rows.length - 1; i > 0; i--) {
                    tmpgvItems.deleteRow(i);
                     for (j = gvItems.rows.item(0).cells.length - 1; j >= 0; j--) {
                        if (j > fixedCellsCount-1) {
                            tmpgvFixed.rows.item(i).deleteCell(j);
                        }
                        else {
                            gvItems.rows.item(i).deleteCell(j);
                        }
                    }
                }
                gvItems.deleteRow(0);
                tmpgvFixed.deleteRow(0);
                
                //conner
                var tmpgvConner = tmpgvItems.cloneNode(true);
                
                for (j = tmpgvItems.rows.item(0).cells.length - 1; j >= 0; j--) {
                    if (j > fixedCellsCount - 1) {
                        tmpgvConner.rows.item(0).deleteCell(j);
                    }
                    else {
                        tmpgvItems.rows.item(0).deleteCell(j);
                    }
                }

                document.getElementById("divShowItemsHeader").appendChild(tmpgvItems);
                tmpgvConner.style.width = "100%";
                document.getElementById("divShowItemsConner").appendChild(tmpgvConner);
                tmpgvFixed.style.width = "100%";
                document.getElementById("divShowItemsFixed").appendChild(tmpgvFixed);

            }
            catch (je) {
                alert(je);
            }
        }
        function ScrollWithSameLeftItems(div) {
            document.getElementById("divShowItemsHeaderScroll").scrollLeft = div.scrollLeft;
            document.getElementById("divShowItemsFixedScroll").scrollTop = div.scrollTop;
        }
        function ShowMouseOverRowItems(row) {
            var rowIndex = row.rowIndex;

            if (rowIndex != GetSelectedRowIndexItems()) {
                var gvItemRowsAll = document.getElementsByName(row.id);
                for (var i = 0; i < gvItemRowsAll.length; i++) {
                    gvItemRowsAll[i].style.backgroundColor = "pink";
                }
            }
        }
        function ShowMouseOutRowItems(row) {
            var rowIndex = row.rowIndex;

            if (rowIndex != GetSelectedRowIndexItems()) {
                var gvItemRowsAll = document.getElementsByName(row.id);
                for (var i = 0; i < gvItemRowsAll.length; i++) {
                    gvItemRowsAll[i].style.backgroundColor = "white";
                }
            }
        }

        function ShowSelectRowItems(row) {
            var selectedindex = GetSelectedRowIndexItems();

            if (selectedindex != -1) {
                var oldName;
                if (document.all) {
                    oldName = row.parentElement.rows.item(selectedindex).id;
                } else {
                oldName = row.parentNode.rows.item(selectedindex).id;
                }
                var gvItemRowsAllOld = document.getElementsByName(oldName);
                for (var i = 0; i < gvItemRowsAllOld.length; i++) {
                    gvItemRowsAllOld[i].style.backgroundColor = "white";
                }
            }
            var gvItemRowsAll = document.getElementsByName(row.id);
            for (var i = 0; i < gvItemRowsAll.length; i++) {
                gvItemRowsAll[i].style.backgroundColor = "#316AC5";
            }
            
            SetSelectedRowIndexItems(row.rowIndex);
        }
        function GetSelectedRowIndexItems() {
            if (document.getElementById("txtSelectedRowIndexItems").value == "") {
                return -1;
            }
            return parseInt(document.getElementById("txtSelectedRowIndexItems").value, 10);
        }
        function SetSelectedRowIndexItems(rowindex) {
            document.getElementById("txtSelectedRowIndexItems").value = rowindex;
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <table border ="0" cellpadding="0" cellspacing ="0">
    <tr>
        <td>
            <div id="divShowItemsConnerScroll" style="width:100px; border:solid 1px;border-bottom-width:0px;border-right-width:0px;background-color:rgb(177,242,168);overflow:hidden;">
            <div id="divShowItemsConner"></div>
            </div>
        </td>
        <td><div id="divShowItemsHeaderScroll" style="border:solid 1px;width:383px;border-bottom-width:0px;background-color:rgb(177,242,168);overflow:hidden;">
            <div id="divShowItemsHeader"></div>
            </div>
        </td>
    </tr>
    <tr>
        <td valign="top" >
            <div id="divShowItemsFixedScroll" style="width:100px; border:solid 1px;border-right-width:0px;height:183px;overflow:hidden;">
            <div id="divShowItemsFixed"></div>
            </div>
        </td>
        <td  valign="top" >
            <div id="divShowItemsDetails" style="border:solid 1px;height:200px;width:400px;overflow:scroll;" onscroll="ScrollWithSameLeftItems(this);">
                <asp:GridView ID="gvShowItemsDetails" name="gvShowItemsDetails" runat="server"  
                    AutoGenerateColumns="False" Width="882px" HeaderStyle-Height="20px" 
                    RowStyle-Height="20px" onrowdatabound="gvShowItemsDetails_RowDataBound">
                <Columns>
                    <asp:TemplateField>
                        <HeaderStyle Wrap="False" Width="30px" HorizontalAlign="Center" />
                        <ItemStyle Wrap="False"  Width="30px" HorizontalAlign="Center"/>
                        <HeaderTemplate>S</HeaderTemplate>
                        <ItemTemplate><asp:CheckBox ID="ckSelected" runat="server" Checked='<%# (DataBinder.Eval(Container.DataItem, "SELECTED")).ToString() == "1" %>'  /></ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField>
                        <HeaderStyle Wrap="False" Width="30px" HorizontalAlign="Center" />
                        <ItemStyle Wrap="False"  Width="30px" HorizontalAlign="Center"/>
                        <HeaderTemplate>NO</HeaderTemplate>
                        <ItemTemplate><%# gvShowItemsDetails.Rows.Count + 1 %></ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="NAME1">
                        <HeaderStyle Wrap="False" Width="170px" HorizontalAlign="Left" />
                        <ItemStyle Wrap="False"  Width="170px" HorizontalAlign="Left"/>
                        <ItemTemplate><%#DataBinder.Eval(Container.DataItem, "NAME1")%></ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="NAME2">
                        <HeaderStyle Wrap="False" Width="170px" HorizontalAlign="Left" />
                        <ItemStyle Wrap="False"  Width="170px" HorizontalAlign="Left"/>
                        <ItemTemplate><%#DataBinder.Eval(Container.DataItem, "NAME2")%></ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="NAME3">
                        <HeaderStyle Wrap="False" Width="230px" HorizontalAlign="Left" />
                        <ItemStyle Wrap="False"  Width="230px" HorizontalAlign="Left"/>
                        <ItemTemplate><%#DataBinder.Eval(Container.DataItem, "NAME3")%></ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="NAME4">
                        <HeaderStyle Wrap="False"  Width="90px" HorizontalAlign="Left" />
                        <ItemStyle Wrap="False"  Width="90px" HorizontalAlign="Left"/>
                        <ItemTemplate><%#DataBinder.Eval(Container.DataItem, "NAME4")%></ItemTemplate>
                    </asp:TemplateField>
                </Columns>
                </asp:GridView>
            </div>
        </td>
    </tr>
    </table>
    <asp:TextBox ID="txtSelectedRowIndexItems" TabIndex="-1" MaxLength="255"  style="display:none" runat="server" Width="0px"></asp:TextBox>
    </div>
    </form>
</body>
</html>
--------------------编程问答--------------------

Server:
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack) 
        {
            InitBlankDetailsItemsDataTable();
        }
//固定2列
        this.ClientScript.RegisterStartupScript(this.GetType(), "showheader", "FixedGridViewHeaderItems('" + this.gvShowItemsDetails.ClientID + "','2');", true);
    }

    protected void InitBlankDetailsItemsDataTable()
    {
        DataTable dataItems = new DataTable();
        DataRow dr;
        dataItems = new DataTable();
        dataItems.Columns.Add("ITEMTYPE", typeof(String));
        dataItems.Columns.Add("SELECTED", typeof(String));
        dataItems.Columns.Add("NAME0", typeof(String));
        dataItems.Columns.Add("NAME1", typeof(String));
        dataItems.Columns.Add("NAME2", typeof(String));
        dataItems.Columns.Add("NAME3", typeof(String));
        dataItems.Columns.Add("NAME4", typeof(String));
        dataItems.Columns.Add("NAME5", typeof(String));
        dataItems.Columns.Add("NAME6", typeof(String));

        for (int i = 0; i < 500; i++)
        {
            dr = dataItems.NewRow();
            dr["SELECTED"] = "1";
            dr["NAME1"] = i.ToString();
            dataItems.Rows.Add(dr);
        }
        dataItems.AcceptChanges();

        this.gvShowItemsDetails.DataSource = dataItems;
        this.gvShowItemsDetails.DataBind();
    }

    protected void gvShowItemsDetails_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {  
                e.Row.Style.Add("cursor", "hand");
                e.Row.Attributes.Add("id", "gvShowItemsDetails_Row" + e.Row.RowIndex.ToString());
                e.Row.Attributes.Add("onmouseover", "javascript:ShowMouseOverRowItems(this);");
                e.Row.Attributes.Add("onmouseout", "javascript:ShowMouseOutRowItems(this);");
                e.Row.Attributes.Add("onclick", "javascript:ShowSelectRowItems(this);");
        }
    }
}
--------------------编程问答-------------------- 关注。。。 --------------------编程问答-------------------- 参考 --------------------编程问答-------------------- FIREFOX中行选中颜色,少了一句代码
RowDataBound事件中
e.Row.Attributes.Add("name", "gvShowItemsDetails_Row" + e.Row.RowIndex.ToString()); --------------------编程问答--------------------
引用 4 楼 rickjelly2004 的回复:
FIREFOX中行选中颜色,少了一句代码
RowDataBound事件中
e.Row.Attributes.Add("name", "gvShowItemsDetails_Row" + e.Row.RowIndex.ToString());
--------------------编程问答-------------------- ren ne --------------------编程问答-------------------- 如果用正则替换,是否能够提高速度呢? --------------------编程问答-------------------- --------------------编程问答-------------------- 最好是不要一下取500条,比如先取50条,够页面显示的就可以了。
既然是表头固定,那么肯定有下拉滚动条了,js写当下拉时(貌似是onscroll事件)执行ajax取剩下的N条,直到取完 --------------------编程问答-------------------- 你可以看一下:http://user.qzone.qq.com/你的QQ号/infocenter
这个页面的效果就是分布取数据的,页面滚动时才去取剩下的 --------------------编程问答-------------------- 另外
  e.Row.Style.Add("cursor", "hand");
  e.Row.Attributes.Add("id", "gvShowItemsDetails_Row" + e.Row.RowIndex.ToString());
  e.Row.Attributes.Add("onmouseover", "javascript:ShowMouseOverRowItems(this);");
  e.Row.Attributes.Add("onmouseout", "javascript:ShowMouseOutRowItems(this);");
  e.Row.Attributes.Add("onclick", "javascript:ShowSelectRowItems(this);");
这些代码的onmouseover onclick等事件如果用jquery动态给行去加事件控制,速度应该会快很多 --------------------编程问答-------------------- 稍微改善了一下,1000行10列,10秒左右
javascript的方法修正了,可能把appendChild全部替换成innerHTML可能更快。

        function FixedGridViewHeaderItems(gvID, fixedCellsCount) {
            try {
                var gvItems = document.getElementById(gvID);
                var rowsCount;
                var cellsCount;
                rowsCount = gvItems.rows.length;
                cellsCount = gvItems.rows.item(0).cells.length;
                // header(LR)
                var headerL = gvItems.cloneNode(false);
                var headerR = gvItems.cloneNode(false);
                
                // Item(L)
                var itemL = gvItems.cloneNode(false);
                var itemR = gvItems.cloneNode(false);
                
                headerL.appendChild(gvItems.rows.item(0).cloneNode(true));
                headerR.appendChild(gvItems.rows.item(0).cloneNode(true));
                
                for (j = cellsCount-1; j >=0; j--) {
                    if (j > fixedCellsCount - 1) {
                        headerL.children[0].removeChild(headerL.children[0].children[j]);
                    }
                    else {
                        headerR.children[0].removeChild(headerR.children[0].children[j]);
                    }
                }
                
                for (i = 1; i < rowsCount; i++) {
                    var itr = gvItems.rows.item(i).cloneNode(false);
                    var iRtr = gvItems.rows.item(i).cloneNode(false);
                    var iCell, iRCell;

                    for (j = 0; j < cellsCount; j++) {
                        if (j < fixedCellsCount) {
                            iCell = gvItems.rows.item(i).cells.item(j).cloneNode(true);
                            itr.appendChild(iCell);
                        }
                        else {
                            iRCell = gvItems.rows.item(i).cells.item(j).cloneNode(true);
                            iRtr.appendChild(iRCell);
                        }
                    }
                    itemL.appendChild(itr);
                    itemR.appendChild(iRtr);
                }
                
                if (document.all) {
                    document.getElementById("divShowItemsHeader").innerHTML = headerR.outerHTML;
                    headerL.style.width = "100%";
                    document.getElementById("divShowItemsCorner").innerHTML = headerL.outerHTML;
                    itemL.style.width = "100%";
                    document.getElementById("divShowItemsFixed").innerHTML = itemL.outerHTML;
                    document.getElementById("divShowItemsDetails").innerHTML = itemR.outerHTML;
                }
                else {
                    var headerLDiv = document.createElement("div");
                    var headerRDiv = document.createElement("div");
                    var itemLDiv = document.createElement("div");
                    var itemRDiv = document.createElement("div");
                    headerL.style.width = "100%";
                    itemL.style.width = "100%";
                    headerLDiv.appendChild(headerL);
                    headerRDiv.appendChild(headerR);
                    itemLDiv.appendChild(itemL);
                    itemRDiv.appendChild(itemR);
                    
                    document.getElementById("divShowItemsCorner").innerHTML = headerLDiv.innerHTML;
                    document.getElementById("divShowItemsHeader").innerHTML = headerRDiv.innerHTML;
                    document.getElementById("divShowItemsFixed").innerHTML = itemLDiv.innerHTML;
                    document.getElementById("divShowItemsDetails").innerHTML = itemR.outerHTML;
                }

            }
            catch (je) {
                alert(je);
            }
        }
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,