zoukankan      html  css  js  c++  java
  • 母版页中对控件ID的处理

      本篇技巧和诀窍记录的是:母版页中对控件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%>"); //推荐在我们设计时往往就会出现一些莫名其妙的问题,我想我们遇到问题时,冷静思考,把握主次,从底层框架入手,纠其原因,相信最终会找到答案。
  • 相关阅读:
    java编译错误No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A(
    java 2中创建线程方法
    动态规划基本思想
    关于eclipse编译一个工程多个main函数
    java Gui初识
    Eclipse中java项目的打包
    java 播放声音
    把资源文件夹导入到eclipse中
    Java建立JProgressBar
    How to grant permissions to a custom assembly that is referenced in a report in Reporting Services
  • 原文地址:https://www.cnblogs.com/soundcode/p/2039932.html
Copyright © 2011-2022 走看看