母版页和 JavaScript document.getElementById






4.66/5 (31投票s)
本文讨论了从 JavaScript 访问母版页内控件时遇到的问题,并提供了一个快速解决方案。
引言
母版页是 ASP.NET 2.0 的最佳特性之一。但是,如果您是 .NET 2.0 和母版页的初学者,您将会在使用 JavaScript 访问放置在母版页内的控件时遇到困难。每当一个控件被放置在母版页内时,其客户端 ID 就会发生改变。由于客户端 ID 的改变,在 JavaScript 中控件的 document.getElementById(serverID)
将无法正常工作。在本文中,我将讨论获取母版页中控件的客户端 ID 以在 JavaScript 中使用的一个最简单的解决方案。
背景
每当一个控件位于母版页内时,该控件的客户端 ID 将会附加其内容占位符 ID。因此,对于 ID 为“txtTest
”的元素,新的客户端 ID 将类似于“ctl00_ContentPlaceHolder1_ txtTest
”。
因此,当您尝试使用 document.getElementById(‘txtTest’)
时,您将无法访问 JavaScript 中的 txtTest
文本框。您需要通过调用 document.getElementById(‘ctl00_ContentPlaceHolder1_ txtTest’)
来访问它。
为了避免硬编码非常长的客户端 ID,我们可以使用 document.getElementById('<%=txtTest.ClientID%>')
来访问该控件。这将使我们能够访问 txtTest
。现在,只要脚本与 ASPX 页面内联,即脚本作为 ASPX 页面的一部分包含在内,这就可以正常工作。但是,如果您将脚本放在单独的 .js 文件中,并通过指定其位置将其添加到 ASPX 页面中,则同样的方法将无法奏效。
因此,在这种情况下,为了访问该控件,我们必须硬编码控件的 ID。但是,硬编码并不是理想的编码方式。为了避免这种情况,我们可以做的是维护客户端 ID 和服务器 ID 之间的映射。在 JavaScript 代码中,我们可以通过给出控件的服务器 ID 来获取控件的客户端 ID。这可以通过如下所示的方式实现。
使用代码
如上所述,这可以通过这里显示的方式实现。首先,我们需要声明两个数组;第一个数组将包含所需控件的服务器 ID,第二个数组将包含服务器控件的客户端 ID,顺序相同。在客户端注册这两个数组。现在,创建一个 JavaScript 函数,该函数将接受服务器 ID,并将其与数组中可用的服务器 ID 进行比较,并给出其在数组中的位置。然后,该函数将从客户端 ID 数组中的相同位置返回匹配的客户端 ID。我认为这是维护客户端和服务器 ID 之间映射的最简单方法之一。
下面的代码显示了数组的声明,以及代码隐藏中 JavaScript 函数的声明。
// This is the method used to register the array
// of the clientid's as well as the serverid's
// Also this method registers the function GetClientId, which is used
// to get the client id provided server id is supplied
public void RenderJSArrayWithCliendIds(params Control[] wc)
{
if (wc.Length > 0)
{
StringBuilder arrClientIDValue = new StringBuilder();
StringBuilder arrServerIDValue = new StringBuilder();
// Get a ClientScriptManager reference from the Page class.
ClientScriptManager cs = Page.ClientScript;
// Now loop through the controls and build the client and server id's
for (int i = 0; i < wc.Length; i++)
{
arrClientIDValue.Append("\"" +
wc[i].ClientID + "\",");
arrServerIDValue.Append("\"" +
wc[i].ID + "\",");
}
// Register the array of client and server id to the client
cs.RegisterArrayDeclaration("MyClientID",
arrClientIDValue.ToString().Remove(arrClientIDValue.ToString().Length - 1, 1));
cs.RegisterArrayDeclaration("MyServerID",
arrServerIDValue.ToString().Remove(arrServerIDValue.ToString().Length - 1, 1));
// Now register the method GetClientId, used to get the client id of tthe control
cs.RegisterStartupScript(this.Page.GetType(), "key",
"\nfunction GetClientId(serverId)\n{\nfor(i=0; i<MyServerID.length; i++)" +
"\n{\nif ( MyServerID[i] == serverId )\n" +
"{\nreturn MyClientID[i];\nbreak;\n}\n}\n}", true);
}
}
我们可以将此代码作为所有 UI 页面的公共类的一部分,例如页面基类,以便在我们需要访问 JavaScript 中的控件的每个页面中,我们可以简单地调用该函数,并将要访问的控件作为参数。
// Here we need to register the client ids to the client,
// so that the same can be used in the javascript
// If there are nultiple controls make it by comma seperated..
RenderJSArrayWithCliendIds(txtTest);
这是在客户端和服务器 ID 之间建立映射的最简单方法之一。在这里,无需担心从外部 JavaScript 文件访问母版页内的控件。
现在,我们可以在 JavaScript 中访问在 RenderJSArrayWithCliendIds
函数中给出的元素,如下所示
var TextBox = document.getElementById(GetClientId("txtTest"));
这将解决因放置在母版页内的控件的客户端 ID 发生更改而引起的任何问题。