[转]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 ...
随机推荐
- Spring学习笔记:Spring动态组装打印机
一.如何开发一个打印机 1.可灵活配置使用彩色魔盒或灰色魔盒 2.可灵活配置打印页面的大小 二.打印机功能的实现依赖于魔盒和纸张 三.步骤: 1.定义墨盒和纸张的接口标准 package cn.pri ...
- rabbimq之死信队列
死信队列:DLX,dead-letter-exchange 利用dlx,当消息在一个队列中变成死信(dead message)之后,它能被重新publish到另一个exchange,这个exchang ...
- JBPM学习第1篇:入门与安装
1.相关关键词 BPM:全称Business Process Management,即业务流程管理 BPEL:全称为Business Process Execution Language,即业务流程执 ...
- Js的核心:找到DOM
掌握 JavaScript 的核心之一:DOM,能够熟悉DOM相关操作,了解JavaScript事件机制 一.使用getElementById().getElementsByTagName().chi ...
- Redis学习笔记(二) ---- PHP操作Redis各数据类型
Redis 一.使用PHP操作Redis存储系统中的各类数据类型方法 1.String(字符串)操作 <?php // 1. 实例化 $redis = new Redis; // 2. 连接 r ...
- VScode设置jsx语法自动补全
1.打开VScode 2.文件>首选项>设置 3.加上以下配置项就可以了 "emmet.includeLanguages": { "javascript&qu ...
- Perl学习笔记(1)----入门
在UNIX/Linux 系统上,打开命令终端,输入 'rpm -q perl' 查看系统是否安装了 perl ---- 在自己的CentOS7 系统上,默认自带了 perl 软件: root@javi ...
- UMTSkeeper: keep your UMTS/GPRS/GSM connection alive automatically
UMTSkeeper: keep your UMTS/GPRS/GSM connection alive automatically by Elias from Mintaka This page i ...
- redis 在linux安装
转自:http://futeng.iteye.com/blog/2071867 下载 官网下载 安装 tar zxvf redis-2.8.9.tar.gz cd redis-2.8.9 #直接mak ...
- 24点-code1
#include <iostream> #include <string> #include <cstdlib> #include <cmath> us ...