[转]ASP.NET母版页中对控件ID的处理
一、问题提出
由于总体排版和设计的需要,我们往往创建母版页来实现整个网站的统一性,最近我由于统一性的需要,把原来整个项目单独的页面全部套用了母版页。但是出现了一个错误……在我的Blog中记录一下,方便大家参考。
二、 抽象模型
由于整个页面内容过多,所以我把这个页面中最为本质的问题抽象出来。原来单一页面,就是利用按钮触发JS事件,在文本域中插入“(_)”功能,其实现代码如下:
- <head id="Head1" runat="server">
- <title>单一页面抽象模型-YJingLee</title>
- <script language="javascript" type="text/javascript">
- // <!CDATA[
- function insert() {
- document.getElementById("txt").value=document.getElementById("txt").value+"(__)";
- return;
- }
- // ]]>
- </script>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- <textarea id="txt" runat="server" name="txt" rows="10" cols="50"></textarea>
- <asp:Button ID="btnInsert" runat="server" Text="服务器端插入(_)" OnClientClick="insert();" />
- <input id="btnInsert2" name="insert" onclick="insert();" type="button" value="客户端插入(_)"
- runat="server" /></div>
- </form>
- </body>
- </html>
上述页面可以正常使用。后来使用模板页后,其代码如下:
- <asp:content id="Content1" contentplaceholderid="ContentPlaceHolder1" runat="Server">
- <script language="javascript" type="text/javascript">
- // <!CDATA[
- function insert() {
- document.getElementById("txt").value = document.getElementById("txt").value + "(__)";
- return;
- }
- // ]]>
- </script>
- <div>
- <textarea id="txt" runat="server" name="txt" rows="10" cols="50"></textarea>
- <asp:Button ID="btnInsert" runat="server" Text="服务器端插入(_)" OnClientClick="insert();"/>
- <input id="btnInsert2" name="insert" onclick="insert();" type="button"
- value="客户端插入(_)" runat="server"/></div>
- </asp:content>
复制代码
当打开后按下按钮出现了“Microsoft JScript 运行时错误: 'document.getElementById(...)' 为空或不是对象”。这是什么原因呢?原来好好的,怎么套用个母版页就出现这个奇怪的问题呢?困扰了好久,和朋友讨论了一下,终于找到了答案……
三、分析本质
原来我们仔细看看其生成的HTML代码:单一页面:
- <form name="form1" method="post" action="Default.aspx" id="form1">
- <textarea name="txt" id="txt" rows="10" cols="50"></textarea>
- <input type="submit" name="btnInsert" value="服务器端插入(_)" onclick="insert();" id="btnInsert" />
- <input name="btnInsert2" type="button" id="btnInsert2" onclick="insert();" value="客户端插入(_)" />
- </form>
再看看套用母版页之后,生成的HTML代码:
- <form name="aspnetForm" method="post" action="Default2.aspx" id="aspnetForm">
- <textarea name="ctl00$ContentPlaceHolder1$txt" id="ctl00_ContentPlaceHolder1_txt"
- rows="10" cols="50"></textarea>
- <input type="submit" name="ctl00$ContentPlaceHolder1$btnInsert" value="服务器端插入(_)"
- onclick="insert();" id="ctl00_ContentPlaceHolder1_btnInsert" />
- <input name="ctl00$ContentPlaceHolder1$btnInsert2" type="button" id="ctl00_ContentPlaceHolder1_btnInsert2"
- onclick="insert();" value="客户端插入(_)" />
- </form>
是不是看到问题了,源文件控件元素的ID和生成HTML文件的ID不一致。表单from的name属性和id属性变成了aspnetForm,控件的id属性被无缘无故了加上了ctl00_ContentPlaceHolder1_前缀,其name属性也加上了 ctl00$ContentPlaceHolder1$前缀。
这下知道了,难怪提示“'document.getElementById(...)' 为空或不是对象”的错误了,原来生成页面后其ID都变了。那么我们如何解决它呢?既然他id变了,我们就把JS代码id改为生成后的id。代码如下:
- function insert() {
- document.getElementById("ctl00$ContentPlaceHolder1$txt").value =
- document.getElementById("ctl00$ContentPlaceHolder1$txt").value + "(__)";
- return;
- }
- //或者
- function insert() {
- document.getElementById("ctl00_ContentPlaceHolder1_txt").value =
- document.getElementById("ctl00_ContentPlaceHolder1_txt").value + "(__)";
- return;
- }
好了,问题解决了,不过想想有什么更好的办法呢?到底为什么呢?其实分析一下,它是后来生成的客户端id,我们可以用C#语句Control的 ClientID属性,像这样写:txt.ClientID; txt还是原来控件的id,后面的ClientID就是新生成的id。txt.ClientID是从程序里取到的后来生成新的id,这样不是更好吗。修改代码如下:
- function insert() {
- document.getElementById("<%=txt.ClientID %>").value =
- document.getElementById("<%=txt.ClientID %>").value + "(__)";
- return;
- }
还有在后台Request.Form["txt"]键值需要改变,必须变为Request.Form["<%=txt.ClientID %>"]才能接收到页面的值。想想如果想要得到ID的control是一个用户控件的话,当生成页面后尽管能得到其ClientID,但是却得不到这个对象,所以也就不能设置或获得其属性了。比如,我要做的这个用户控件,由三个DropDownList组成,可是我却想得到一个完整的日期值(指在客户端),一种思路是先获得三个DropDownList的ClientID,然后再由ID1.value+ID2.value+ID3.value取得,可是如果你一个页面上需要放多个这样的用户控件的话,你需要取得多少个ClientID?显然这样做的话,工作量会很大,而且要操作众多的对象,很容易出错。
四、总结
这一类问题我像在我们编写程序时往往经常会遇到,总结一下:这应该属于“使用了MasterPage,或者GridView中的模版列后所有元素 ID不一致问题”。由于种种原因(比如使用了MasterPage,或者GridView中的模版列),一个控件在设计时的ID往往不同于生成页面后的 ID,为了获得控件客户端ID,我们可以从生成的页面入手,取控件id修改方法:
- document.getElementById("ctl00$编辑区ID$控件ID");
- document.getElementById("ctl00_编辑区ID_控件ID");
- document.getElementById("<%=控件名ID.ClientID%>"); //推荐
在我们设计时往往就会出现一些莫名其妙的问题,我想我们遇到问题时,冷静思考,把握主次,从底层框架入手,纠其原因,相信最终会找到答案。
来源:http://club.topsage.com/thread-480447-1-1.html
[转]ASP.NET母版页中对控件ID的处理的更多相关文章
- Asp.Net 之 母版页中对控件ID的处理
一.问题提出 由于总体排版和设计的需要,我们往往创建母版页来实现整个网站的统一性,最近我由于统一性的需要,把原来整个项目单独的页面全部套用了母版页.但是出现了一系列失效错误. 二. 抽象模型 由于整个 ...
- 041. asp.net中内容页访问母版页中的控件
母版页运行机制: 用户通过输入内容也的URL来请求某个页面, 获取该页面后, 读取@Page指令, 如果该指令引用了一个母版页, 则也读取该母版页, 如果也是第一次请求这两个页面, 则母版页和被请求的 ...
- 母版页中ContentPlaceHolder 控件的作用
文章转自 http://wenku.baidu.com/link?url=7sLN0ihgZQ1XfX47b_y8qbpIVjS5T75Q1xvaoyIQ6OiKIgvzyVyRccnU9e9fqo ...
- 母版页改变被嵌套的页面中的控件ID的解决方法
使用过模板页的朋友都会很纳闷,怎么页面的用js通过getElementById(“id”):找不到对象.查看了页面源代码才发现,原来控件的ID变了,这是母版页导致的.因为母版页怕母版页本身页面中的控件 ...
- 向asp.net项目中添加控件AspNetPager
1.打开项目,把.dll文件放入项目中: 2.在工具栏中添加一个自定义选项卡
- [转载]ASP.NET中TextBox控件设立ReadOnly="true"后台取不到值
原文地址:http://www.cnblogs.com/yxyht/archive/2013/03/02/2939883.html ASP.NET中TextBox控件设置ReadOnly=" ...
- asp.net中验证控件的使用方法
用于检查是否有输入值 :RequiredFieldValidator(必须字段验证) 按设定比较两个输入 :CompareValidator(比较验证) 输入是否在指定范围 :RangeValidat ...
- ASP.NET 后台不识别ASPX中的控件
请问后台不识别ASPX中的控件,怎么解决 这个程序是在网上下载的 C# code <asp:DataGrid runat="server" ID="dgList1& ...
- ASP.NET在母版页或内容页上获取控件ID
原本想给一个button添加一个confirm,不同的分数提示不同的信息(大于80合格,小于80不合格,提示是否提交),最开始用了button.Atribute.Add();但是它每次获取到的是lab ...
随机推荐
- Gradle sync failed: Cannot set the value of read-only property 'outputFile'
错误 Gradle sync failed: Cannot set the value of read-only property 'outputFile' 原因 gradle打包,自定义apk名称代 ...
- c语言printf实现同一位置打印输出
控制台同一位置打印输出,例如:进度1%->100%在同一位置显示.刚学习c语言的时候一直想做起来,可惜查询好多资料不行.时隔6年多,空闲之余又想起这个问题,便决定一试,虽然c语言已经几乎忘光了, ...
- 解决JVM内存溢出问题
今天遇到了一个问题,当我在增加配置文件(*.xml)内容的时候,重新启动tomcat6时,控制台报错:java.lang.StackOverflowError: 即,栈溢出错误. 内存溢出,即程序运行 ...
- Nginx 503错误总结
nginx 503错误(Service Temporarily Unavailable 服务暂时不可用): 503是一种HTTP状态码,由于临时的服务器维护或者过载,服务器当前无法处理请求.这个状况 ...
- css3打包后自动追加前缀插件:autoprefixer
用vue-cli构建的项目脚手架已经帮你把autoprefixer的配置做好了,自己不需要做什么改动就会自动加前缀: 下面一起看看涉及到autoprefixer这个插件的一些配置: 1,postcss ...
- 解决PUTTY出现中文乱码问题
Putty在默认情况下没有使用UTF-8编码,因此在显示中文的时候会出现乱码.解决方法非常简单:按照下图,在连接之前,左边窗口中的“转换”选项卡(如图所示),然后在右边“假定接收的数据字符集”的下拉选 ...
- sql语句查询一个表里面无重复并且按照指定字段排序的sql语句
SELECT a.* FROM product_template a INNER JOIN (SELECT p_id,MAX(ID) as max_id FROM product_template w ...
- Android学习——文件存储
在Andriod开发中,文件存储和Java的文件存储类似.但需要注意的是,为了防止产生碎片垃圾,在创建文件时,要尽量使用系统给出的函数进行创建,这样当APP被卸载后,系统可以将这些文件统一删除掉.获取 ...
- easyui的解析器Parser
平时使用easyui做框架开发时,都知道easyui的模块组件能通过属性方法或js方法来渲染,本质上是通过parser解析器来处理实现的,因为多数情况下都是自动触发完成整个页面的解析,所以没有感觉到它 ...
- tcp-full.cc
ns2--tcp-full.cc /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */ /* * Copy ...