注:此系列记录在我实际开发中遇到的问题和收藏一些技巧文章。

本篇技巧和诀窍记录的是:母版页中对控件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%>"); //推荐

在我们设计时往往就会出现一些莫名其妙的问题,我想我们遇到问题时,冷静思考,把握主次,从底层框架入手,纠其原因,相信最终会找到答案。

Tips/Tricks#0:母版页中对控件ID的处理相关推荐

  1. 嵌套母版页中的控件访问

    嵌套母版页中的控件访问 左直拳 嵌套母版页中的控件访问很别扭. 如果一个内容页对应一个没有嵌套的母版页,访问这个母版页上的控件众所周知:类似(Button)Page.Master.FindContro ...

  2. html更改textbox的id,NET开发-WebForm中TextBox控件ID、Text、TextModel等属性的使用

    .NET开发-WebForm中的TextBox控件 1. TextBox概述 在ASP.NET Web应用程序中,TextBox控件是文本框控件.用于在网页表单中,让用户输入文本内容,收集用户信息,然 ...

  3. listview控件Android,Android中ListView控件的简单使用

    文章引自郭霖<第一行代码> ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚动出屏幕 使用LIstView控件 1 在布局文件中引入Li ...

  4. Asp.net 2.0 中获取控件输出的Html代码 (转)

    将Asp.net 控件的呈现html获取,在不少场合会用到,比如生成静态页时 以下代码选自 Asp.net 2.0 高级编程 转自:Asp.net 2.0 中获取控件输出的Html代码 public  ...

  5. 使用母版页后出现控件,使用FindControl找不到指定控件

    在注册页面中,为了重置页面上所有的控件,编写了页面中重置按钮的单击事件 protected void btnReset_Click(object sender, EventArgs e) { Labe ...

  6. (转) ASP.NET 2.0:使用用户控件和定制的Web部件个人化你的门户网站(二)

    Web部件目录 我们已经见过了如何在 WebPartZones 控件中事先放入Web部件.你还可以用另外一种方法完成这个功能,那就是允许用户在运行时添加新的Web部件.通过使用 CatalogZone ...

  7. [转]利用ASP.NET 2.0创建自定义Web控件(1)

    原址:http://hi.baidu.com/sjbh/blog/item/cc58fd1bd35d3ad2ad6e7593.html   简介 从使用基本的文本编辑器到创作标记页面,Web 开发已经 ...

  8. VS Tips]Visual Studio 2008 Toolbox里控件消失(#13119)的问题

    VS Tips]Visual Studio 2008 Toolbox里控件消失(#13119)的问题 今天打开Visual Studio 2008准备写windows form程序的时候, 发现Too ...

  9. 精通 WPF UI Virtualization (提升 OEA 框架中 TreeGrid 控件的性能)

    精通 WPF UI Virtualization (提升 OEA 框架中 TreeGrid 控件的性能) 原文:精通 WPF UI Virtualization (提升 OEA 框架中 TreeGri ...

最新文章

  1. 用户界面设计准则从何而来
  2. 关于面试的一些问题合集
  3. python需要学多久才能找到工作-为什么Python适合初学者,一般要学习多久
  4. 年后开课 | 第 4 期临床基因组家系分析,同时解决科研和临床问题
  5. Python高能小技巧:了解bytes与str的区别
  6. 清空数据库事务日志_通过事务日志增长加快数据库恢复和长期运行的事务
  7. WPS 2019使用技巧及WPS2019政府版最全合集
  8. python中 使用EVO工具 批量评估里程计 脚本
  9. Web Intelligence and Big Data--Final Exam
  10. 3. Zigbee应用程序框架开发指南 - 应用程序框架目录结构
  11. 谷歌地图 经纬加密_Google开始加密搜索
  12. 仿制苏宁易购—静态网页
  13. 惠普打印机驱动下载(电脑系统和打印机型号自动匹配)
  14. Ubuntu 20.04 源码编译Paddle2.2.2
  15. Android 手机浏览器的开发
  16. android水印相机,Android 水印相机开发
  17. CGAL例程:地理信息系统----点云数据生成DSM、DTM、等高线和数据分类
  18. 美国计算机科学专业申请条件,美国CS计算机科学专业申请条件有哪些?
  19. 移动端横屏/强制横屏
  20. SAP采购计划协议计划数量小于收货或发票数量的案例分析

热门文章

  1. Intel汇编语言程序设计学习-第四章 数据传送、寻址和算术运算-上
  2. hdu3460 字典树(打印机)
  3. 【数字信号处理】离散时间信号 ( 离散时间信号知识点 | 信号定义 | 信号分类 | 根据确定性分类 | 根据周期性分类 | 根据离散型分类 )
  4. 【Git】Git 分支管理 ( 删除远程分支 | 查看远程分支 git branch -a | 删除远程分支 git push origin --delete feature1 )
  5. 【Git】Git 基础命令 ( Git 版本库概念 | 创建版本库 git init | 克隆版本库 git clone )
  6. 【C 语言】二级指针作为输入 ( 自定义二级指针内存 | 为 二级指针 分配内存 - 存放 一维指针 | 为每个 一级指针 分配内存 | 释放二维指针内存 )
  7. 【Android 异步操作】Handler 机制 ( MessageQueue 消息队列的阻塞机制 | Java 层机制 | native 层阻塞机制 | native 层解除阻塞机制 )
  8. 【数据挖掘】贝叶斯分类 ( 贝叶斯分类器 | 贝叶斯推断 | 逆向概率 | 贝叶斯公式 | 贝叶斯公式推导 | 使用贝叶斯公式求逆向概率 )
  9. 【数据挖掘】数据挖掘算法 组件化思想 ( 模型或模式结构 | 数据挖掘任务 | 评分函数 | 搜索和优化算法 | 数据管理策略 )
  10. 第3节 sqoop:3、sqoop的入门测试使用