HTMLDocument getElementById for a custom control returns null, why, and is there a different way to access it?
I have the following in an aspx page inside a body tag:
<form id="Form1" method="post" runat="server">
<customControl:menu id="Menu1" runat="server">
</customControl:menu>
</form>
And from a different aspx page I have this javascript function:
<script type="text/javascript">
function testFunction(args, name) {
alert(top.frames[0].document); //gives me [object HTMLDocument]
alert(top.frames[0].document.getElementById("Form1")); //gives me [object HTMLFormElement]
alert(top.frames[0].document.getElementById("Menu1")); //gives me [null]
}
</script>
Why is the third alert giving me null? (The menu
is a control with an ascx
extensi开发者_运维百科on)
Thanks, Voodoo
Let me quote from an article I recently wrote: Take Control Of Web Control ClientID Values in ASP.NET 4
Each server-side Web control in an ASP.NET Web Forms application has an ID property that identifies the Web control and is the name by which the Web control is accessed in the code-behind class. When rendered into HTML, the Web control turns its server-side ID value into a client-side id attribute. Ideally, there would be a one-to-one correspondence between the value of the server-side ID property and the generated client-side id, but in reality things aren't so simple. By default, the rendered client-side id is formed by taking the Web control's ID property and prefixed it with the ID properties of its naming containers. In short, a Web control with an ID of txtName can get rendered into an HTML element with a client-side id like ctl00_MainContent_txtName.
This default translation from the server-side ID property value to the rendered client-side id attribute can introduce challenges when trying to access an HTML element via JavaScript, which is typically done by id, as the page developer building the web page and writing the JavaScript does not know what the id value of the rendered Web control will be at design time.
The Web control's client-side id value can be determined at runtime via the Web control's ClientID property. This is why others have suggested using <%=Menu1.ClientID%> in place of a hard-coded id name.
If you are using ASP.NET 4.0 you have more control over how Web controls render their ID property into a client-side id via the Client. Namely, you can set the Menu's ClientIDMode property to Static to ensure that there is a one-to-one correspondence between the server-side ID property and the client-side id attribute (but you must be careful using this approach).
For more information refer to:
- ASP.NET 4.0 ClientID Overview
- Take Control Of Web Control ClientID Values in ASP.NET 4
Happy Programming!
The id
that is being output by asp.net is probably not Menu1
- asp.net normally concatenates the container names to the control id
, to avoid duplicate id
s in a page.
Use the ClientId
property to get the id
that will be output to the browser:
alert(top.frames[0].document.getElementById("<%:Menu1.ClientId%>")); // .NET 4 syntax
alert(top.frames[0].document.getElementById("<%=Menu1.ClientId%>")); // .NET 2/3/3.5 syntax
When an element is inside a custom control or other such container (e.g. a master page), ASPX creates an id such that the element can have a unique ID on the page (by adding the container name to the element id, etc.). Therefore, you can't use the id that you gave the element in your javascript; it's actual id will be different.
Within the aspx code you can get access to that runtime id by using the ClientId property. Alternately, you can use jQuery and use some other selector (e.g. a name, class, etc.) to identify the element.
Try this
alert(top.frames[0].document.getElementById("<% = Menu1.ClientID %>"));
If you're using 4.0, you can add
ClientIDMode="Static"
to force the ID to remain unchanged.
http://weblogs.asp.net/scottgu/archive/2010/03/30/cleaner-html-markup-with-asp-net-4-web-forms-client-ids-vs-2010-and-net-4-0-series.aspx
精彩评论