• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

[转]ASP.NET母版页中对控件ID的处理

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一、问题提出

由于总体排版和设计的需要,我们往往创建母版页来实现整个网站的统一性,最近我由于统一性的需要,把原来整个项目单独的页面全部套用了母版页。但是出现了一个错误……在我的Blog中记录一下,方便大家参考。

二、 抽象模型

由于整个页面内容过多,所以我把这个页面中最为本质的问题抽象出来。原来单一页面,就是利用按钮触发JS事件,在文本域中插入“(_)”功能,其实现代码如下:

  • <head >
  • <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 >
  • <div>
  • <textarea ></textarea>
  • <asp:Button ID="btnInsert" runat="server" Text="服务器端插入(_)" OnClientClick="insert();" />
  • <input
  • runat="server" /></div>
  • </form>
  • </body>
  • </html>

  • 上述页面可以正常使用。后来使用模板页后,其代码如下:

  • <asp:content >
  • <script language="javascript" type="text/javascript">
  • // <!CDATA[
  • function insert() {
  • document.getElementById("txt").value = document.getElementById("txt").value + "(__)";
  • return;
  • }
  • // ]]>
  • </script>
  • <div>
  •    <textarea ></textarea>
  •    <asp:Button ID="btnInsert" runat="server" Text="服务器端插入(_)"  OnClientClick="insert();"/>
  •    <input
  • value="客户端插入(_)" runat="server"/></div>
  • </asp:content>
  • 复制代码

    当打开后按下按钮出现了“Microsoft JScript 运行时错误: 'document.getElementById(...)' 为空或不是对象”。这是什么原因呢?原来好好的,怎么套用个母版页就出现这个奇怪的问题呢?困扰了好久,和朋友讨论了一下,终于找到了答案……

    三、分析本质

    原来我们仔细看看其生成的HTML代码:单一页面:

  • <form name="form1" method="post" action="Default.aspx" >
  • <textarea name="txt" ></textarea>
  • <input type="submit" name="btnInsert" value="服务器端插入(_)" onclick="insert();" />
  • <input name="btnInsert2" type="button" />
  • </form>

  • 再看看套用母版页之后,生成的HTML代码:

  • <form name="aspnetForm" method="post" action="Default2.aspx" >
  • <textarea name="ctl00$ContentPlaceHolder1$txt"
  • rows="10" cols="50"></textarea>
  • <input type="submit" name="ctl00$ContentPlaceHolder1$btnInsert" value="服务器端插入(_)"
  • onclick="insert();" />
  • <input name="ctl00$ContentPlaceHolder1$btnInsert2" type="button"
  • 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


    鲜花

    握手

    雷人

    路过

    鸡蛋
    该文章已有0人参与评论

    请发表评论

    全部评论

    专题导读
    上一篇:
    我要学ASP.NET MVC 3.0(一): MVC 3.0 的新特性发布时间:2022-07-10
    下一篇:
    asp.netcore3.1+mysql8.0+Hangfire遇到的异常解决记发布时间:2022-07-10
    热门推荐
    热门话题
    阅读排行榜

    扫描微信二维码

    查看手机版网站

    随时了解更新最新资讯

    139-2527-9053

    在线客服(服务时间 9:00~18:00)

    在线QQ客服
    地址:深圳市南山区西丽大学城创智工业园
    电邮:jeky_zhao#qq.com
    移动电话:139-2527-9053

    Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap