Master Pages and JavaScript document.getElementById

译文:

Master Pages 和 JavaScript document.getElementById

介绍

模板页是ASP.NET 2.0的最重要的特性之一。但是,如果对于.NET2.0和模板页是个新手的话,你需要在用javascript访问内置于模板页中的控件这方面颇费点功夫了。每当一个控件被置于模板页中时,它的Client ID将会被修改。当Client ID修改后,在javascript中使用document.getElementById(serverID)访问这些控件将不会奏效。在这篇文章中,我将讨论一种比较简单的方法获得在javascript使用的模板页中控件的Client ID.

背景

当一个控件在模板页中时,这个控件的Client ID将会被附着与他的Content placeholder ID.所以,如果一个元素的ID为txtTest”,那么这个新的Client ID就会像"ctl00_ContentPlaceHolder1_ txtTest”.

所以,当你试着用document.getElementById(‘txtTest’), 你将无法使用javascript来访问txtTest,你需要通过调用document.getElementById(‘ctl00_ContentPlaceHolder1_ txtTest’)来访问它。

为了避免对这个较长的Client ID进行硬编码,我们可以通过使用document.getElementById('<%=txtTest.ClientID%>')访问控件,这样就能够访问txtTest.现在它将会奏效除非javascript与aspx也一致,也就是说,当javascript作为aspx页的一部分时,这样写挺奏效的。但是如果把javascript语句放到单独的.js文件中通过指定路径引用到aspx页面的话,这样写就不行了。

所以,在这个脚本里,为了获取控件,我们不得不硬编码控件的ID,但是硬编码不是编码的理想方式,为了避免这种状况,我们所能做的是在Client ID和Server ID间保持一个映射,在javascript代码中,我们能够根据给定的Server ID获取Client ID,这个将在下面被实现。

使用这些编码

在上面所说的将会在这里实现,第一,我们需要申明两个数组;第一个数组用来存储控件Server ID,第二个数组在同样的位置存放服务器控件的Client ID.在客户端注册这两个数组。现在,生成一个javascript的函数,接收server ID并且用这个server ID和数组中存储的server ID进行比较,给出它在数组中的位置。然后,同样的函数将会根据这个位置在Client ID数组中找到对应的Client ID.我感觉这是保持Client和Server IDs映射的最简单的方法。

这段代码显示了数组的定义以及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访问控件,我们可以把被访问的控件作为参数来调用这个函数。

//这里我们需要把client ids 注册到客户端

//以便能够在javascript中使用同样的

//如果有多个控件,用逗号隔开..

RenderJSArrayWithCliendIds(txtTest);

这是得到Client和Server IDs映射的最简单的方法。这里,没有必要担心在外部javascript文件中访问模板页中的控件。

现在我们可以通过如下代码访问在javascript中被提交到RenderJSArrayWithCliendIds函数中的控件。

var TextBox = document.getElementById(GetClientId("txtTest"));

这个将会解决由于控件在模板页中使得Client IDs改变而产生的任何问题。

 

原文

Introduction

Master Pages is one of the best features of ASP.NET 2.0. But, if you are a beginner in .NET 2.0 and Master Pages, you would get stuck in accessing controls placed inside a Master Page using JavaScript. Whenever a control is placed inside a Master Page, its client ID would be changed. As the client ID is changes, the document.getElementById(serverID) of the control in JavaScript won't work. In this article, I will discuss about one of the simplest solutions to get the client ID of a control in a Master Page for use in JavaScript.

Background

Whenever a control is inside a Master Page, the client ID of the control would get appended with its content placeholder ID. So, for an element with an ID “txtTest”, the new client ID would look something like “ctl00_ContentPlaceHolder1_ txtTest”.

So, when you try to use document.getElementById(‘txtTest’), you will not get access to the txtTest textbox in JavaScript. You need to access it by calling document.getElementById(‘ctl00_ContentPlaceHolder1_ txtTest’).

To avoid hard coding of very long client IDs, we can access the control by using document.getElementById('<%=txtTest.ClientID%>'). This will give us access to txtTest. Now, this will work fine until and unless the script is inline with the ASPX page, i.e., if the script is included as part of the ASPX page. But, the same won’t work if you have the script in a separate .js file and add it to the ASPX page by specifying its location.

So, in this scenario, to get access to the control, we have to hard code the control’s ID. But hard coding is not the ideal way of coding. To avoid this situation, what we can do is maintain a mapping between the client ID and the server ID. In the JavaScript code, we can get the client ID of the control by giving its server ID. This can be achieved as shown below.

Using the code

The above said can be achieved as shown here. First, we need to declare two arrays; the first array will have the server IDs of the required controls, and the second array will have the client IDs of the server controls in the same order. Register these two arrays at the client side. Now, create a JavaScript function which will accept the server ID and will compare the server ID with the available server IDs in the array and will give its position in the array. Then, the same function would return you the matching client ID from the same location in the client IDs array. I feel this is one of the simplest ways of maintaining a mapping between client and server IDs.

The code below shows the declaration of the array, and the declaration of the JavaScript function in the code-behind.

// 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);

        }

    }
We can make this code a part of a common class for all UI pages like a page base, so that in every page we need to access a control in JavaScript, we can simply call the function with the control to be accessed as the parameter.
// 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);

This is one of the simplest ways to have a mapping between client and server IDs. Here, there is no need to worry about accessing a control inside a Master Page from an external JavaScript file.

Now, we can access the elements which are given in the RenderJSArrayWithCliendIds function in the JavaScript as shown below:

var TextBox = document.getElementById(GetClientId("txtTest"));

This will solve any issue arising due to changes in the client IDs of controls placed inside a Master Page.

你可能感兴趣的:(JavaScript)