Javascript 冻结动态栅格的标题行

Javascript 冻结动态栅格的标题行,javascript,asp.net,vb.net,gridview,Javascript,Asp.net,Vb.net,Gridview,我有一个动态创建的gridview。我在运行时将它添加到我的表单中(因此我的HTML源代码没有标记)。我已设法获得滚动条,但我的经理要求我在滚动时冻结标题行。互联网上详尽的搜索只显示了静态gridview示例。我试图实现一个通用的javascript解决方案,但出现了一个错误“Object required”标记这行: var gridWidth = grid.offsetWidth; 以下是我的html源代码: form id="form1" runat="server"> <

我有一个动态创建的gridview。我在运行时将它添加到我的表单中(因此我的HTML源代码没有标记)。我已设法获得滚动条,但我的经理要求我在滚动时冻结标题行。互联网上详尽的搜索只显示了静态gridview示例。我试图实现一个通用的javascript解决方案,但出现了一个错误“Object required”标记这行:

var gridWidth = grid.offsetWidth;  
以下是我的html源代码:

form id="form1" runat="server">
<div>

    <asp:ImageButton ID="ImageButtonExcelExport" runat="server"
        ImageUrl="~/css/images/icons/custom/Excel-16.gif" 
        ToolTip="Export to Excel" PostBackUrl="~/ErrorReportGrid.aspx" />


    <div id="Div1" runat="server" >
    </div>


</div>

<!-- javascript here -->
<script type = "text/javascript">
var GridId = "<%=ErrorCodeGrid.ClientID %>";
var ScrollHeight = 300;
window.onload = function() {
    var grid = document.getElementById(GridId);
    var gridWidth = grid.offsetWidth;
    var gridHeight = grid.offsetHeight;
    var headerCellWidths = new Array();

for (var i = 0; i < grid.getElementsByTagName("TH").length; i++) {
        headerCellWidths[i] = grid.getElementsByTagName("TH")[i].offsetWidth;
    }

grid.parentNode.appendChild(document.createElement("div"));
    var parentDiv = grid.parentNode;
    var table = document.createElement("table");

for (i = 0; i < grid.attributes.length; i++) {
        if (grid.attributes[i].specified && grid.attributes[i].name != "id") {
            table.setAttribute(grid.attributes[i].name, grid.attributes[i].value);
        }
    }

    table.style.cssText = grid.style.cssText;
    table.style.width = gridWidth + "px";
    table.appendChild(document.createElement("tbody"));
    table.getElementsByTagName("tbody")[0].appendChild(grid.getElementsByTagName("TR") [0]);
    var cells = table.getElementsByTagName("TH");
    var gridRow = grid.getElementsByTagName("TR")[0];

for (i = 0; i < cells.length; i++) {
        var width;
        if (headerCellWidths[i] > gridRow.getElementsByTagName("TD")[i].offsetWidth) {
            width = headerCellWidths[i];
        }
        else {
            width = gridRow.getElementsByTagName("TD")[i].offsetWidth;
        }
        cells[i].style.width = parseInt(width - 3) + "px";
        gridRow.getElementsByTagName("TD")[i].style.width = parseInt(width - 3) + "px";
    }

parentDiv.removeChild(grid);
    var dummyHeader = document.createElement("div");
    dummyHeader.appendChild(table);
    parentDiv.appendChild(dummyHeader);
    var scrollableDiv = document.createElement("div");

if (parseInt(gridHeight) > ScrollHeight) {
        gridWidth = parseInt(gridWidth) + 17;
    }

scrollableDiv.style.cssText = "overflow:auto;height:" + ScrollHeight + "px;width:" + gridWidth + "px";
    scrollableDiv.appendChild(grid);
    parentDiv.appendChild(scrollableDiv);
}</script>

您需要为动态网格指定一个ID,以使其具有ClientID

    ErrorCodeGrid = New GridView
    ErrorCodeGrid.ID = "ErrorCodeGrid"
编辑:自从你说它对你不起作用以来,我有了更多的见解

在没有指定ID的情况下,我得到了这个js输出(为了澄清,我删除了一些您的设计属性):

以及gridview:

table cellspacing="0" rules="all" border="1" style="border-collapse:collapse;"
请注意,gridview上没有ID规范,因此javascript无法找到它,我得到了一个空引用

添加我得到的ID:

var GridId = "ErrorCodeGrid";
table cellspacing="0" rules="all" border="1" id="ErrorCodeGrid" style="border-collapse:collapse;" 
请注意,ID是匹配的

如果这对您不起作用,可能您正在使用比我更旧的asp.net版本或其他版本。但底线是这些ID需要匹配

另一个选择,如果你不能让这个工作。将整个代码移动到一个函数中并传入GridId(无论如何,这是个好主意)。然后可以使用动态gridview的ClientId动态注入调用代码

ClientScript.RegisterStartupScript(Me.GetType, "FreezeHeader", "FreezeHeader(" & ErrorCodeGrid.ClientID & ");", True)
编辑2: 使用上面的代码,您需要更改页面中的javascript

替换此代码:

var GridId = "<%=ErrorCodeGrid.ClientID %>";
var ScrollHeight = 300;
window.onload = function() {
var ScrollHeight = 300; // you could move this into the function as well.
var FreezeHeader = function(GridId) {

客户端脚本管理器将只输出对此函数的调用。

您的网格对象是否为空?把这个放在控制台上,试着找到它是空的吗?有注释的区域,上面写着“datasource here”。我有分配datasource的代码,我只是忽略了它,因为它延长了代码。我应该把它包括进去吗?编辑我继续并添加了它。当我在没有javascript的情况下运行代码时。我拉入数据,只是没有一个锁定的标题行。我把它放在控制台上,忽略了那个错误和对应于“var gridHeight=grid.offsetHeight;”的下一个错误。然后它落在我的for循环中,在那里它将grid.getElementsByTagName(“TH”).length注册为null。不确定,我知道如何解决这个问题。我添加了ErrorCodeGrid.ID=“ErrorCodeGrid”,但它仍然不起作用。我想我正在使用ASP.NET2.5。我正在用clientscript尝试您的解决方案。虽然我对使用传统函数感到很舒服,但我并不真正熟悉脚本或脚本文字语法。我需要把javascript翻译成VB吗?从我在网上看到的几个例子来看,它建议我将整个代码体制作成一个没有标记的字符串。我在这里偏离基准了吗?不,你不能把函数翻译成VB。您所做的只是使用客户端脚本管理器调用函数。我将添加一些附加信息。您在HTML中得到的输出是什么?你桌上有身份证吗?它是否与您在javascript中输出的id匹配?
var GridId = "<%=ErrorCodeGrid.ClientID %>";
var ScrollHeight = 300;
window.onload = function() {
var ScrollHeight = 300; // you could move this into the function as well.
var FreezeHeader = function(GridId) {