一、问题提出
由于总体排版和设计的需要,我们往往创建母版页来实现整个网站的统一性,最近我由于统一性的需要,把原来整个项目单独的页面全部套用了母版页。但是出现了一个错误……在我的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%>"); //推荐
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wind8303/archive/2009/01/05/3715634.aspx
分享到:
相关推荐
也同样适用于master页面访问ascx ASP.Net访问母版页(MasterPage)控件、属性、方法及母版页中调用内容页的方法 总结了一下ASP.Net访问母版页(master)控件、属性、方法及母版页中调用内容页(aspx)的方法,供
目 录;;4;Timer控件可以使应用程序方便有效地对系统时间进行控制。 Timer控件能够在一定的时间...如果在母版页中使用了ScriptManager控件,而在内容页中也使用ScriptManager控件,整合在一起的页面就会出现异常。 案
代码如下: <asp ID=”smMaster” runat=”server” ScriptMode=”Auto” EnablePageMethods=”true”> </asp> 2、在Master源码中编写js 代码如下: function NetPost() { //创建实例 var wRequest = new Sys.Net....
掌握母版页的使用。 【实验容】 设计一个个人情况调查程序,程序启动后显示如以下图的页面。用户在填写了、选择了 性别、喜爱的歌手、居住城市、个人爱好后单击"提交〞按钮后,屏幕显示用户填写或选 择的数据信息。...
9.1.6 对GridView控件中的数据进行排序 9.2 其他数据控件的应用 9.2.1 使用Repeater控件显示数据 9.2.2 在Repeater控件中分页显示数据 9.2.3 使用DetailsView控件操作一条记录 9.2.4 使用FormView控件更新和...
数据源控件:用于实现从不同数据源获取数据的功能,可以设置连接信息、查询信息、参数和行为,可以消除ASP.NET中要求的大量的重复性代码。 数据绑定控件:只负责管理与实际数据存储源的连接,并不能呈现任何用户界面...
3.1.7 客户端控件ID 3.2 Web窗体处理阶段 3.2.1 页面框架初始化 3.2.2 用户代码初始化 3.2.3 验证 3.2.4 事件处理 3.2.5 自动数据绑定 3.2.6 清除 3.2.7 页面流示例 3.3 作为控件容器的页面 ...
3.1.7 客户端控件ID 71 3.2 Web窗体处理阶段 73 3.2.1 页面框架初始化 74 3.2.2 用户代码初始化 74 3.2.3 验证 74 3.2.4 事件处理 75 3.2.5 自动数据绑定 75 3.2.6 清除 76 3.2.7 页面流示例 76 ...
MasterPage.master 一个简单的母版页。 9-01.aspx 引用母版页。 MasterPage1.master 创建一个母版页。 9-01.aspx 调用母版页并进行交互。 FMasterPage.master 进行嵌套的父母版页。 SMasterPage....
如果在母版页不显示,是因为textbox的ID控件被重写,右键更改项目为.Net 4.0,控件Textbox属性增加ClientIDMode="Static",防止ID被重写。 如果上传2.0可以,4.0图片失败请在Web.config添加 展示用lable上传图片高...
往网页里拖入一个menu控件,然后添加代码 代码如下: using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.W
MasterPage.master 一个简单的母版页。 9-01.aspx 引用母版页。 MasterPage1.master 创建一个母版页。 9-01.aspx 调用母版页并进行交互。 FMasterPage.master 进行嵌套的父母版页。 SMasterPage.master 引用...
* 视图中幻灯片母版设计与更改(项目符号等) * 增加文字可读性,中间加个圆矩形(绘后下移一层,文字在上)调整透明度 * 选择内容对象,右键项目符号 3. Excel技巧: * 选择B2,冻结窗格,即冻结首行和首列 *...