Tips/Tricks#0:母版页中对控件ID的处理
?
注:此系列記錄在我實際開發(fā)中遇到的問題和收藏一些技巧文章。
本篇技巧和訣竅記錄的是:母版頁中對控件ID的處理。
一、問題提出
由于總體排版和設(shè)計的需要,我們往往創(chuàng)建母版頁來實現(xiàn)整個網(wǎng)站的統(tǒng)一性,最近我由于統(tǒng)一性的需要,把原來整個項目單獨的頁面全部套用了母版頁。但是出現(xiàn)了一個錯誤……在我的Blog中記錄一下,方便大家參考。
二、 抽象模型
由于整個頁面內(nèi)容過多,所以我把這個頁面中最為本質(zhì)的問題抽象出來。原來單一頁面,就是利用按鈕觸發(fā)JS事件,在文本域中插入“(_)”功能,其實現(xiàn)代碼如下:
<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="服務(wù)器端插入(_)" 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="服務(wù)器端插入(_)"??OnClientClick="insert();"/><input?id="btnInsert2"?name="insert"?onclick="insert();"?type="button"value="客戶端插入(_)"?runat="server"/></div> </asp:content>
當(dāng)打開后按下按鈕出現(xiàn)了“Microsoft JScript 運行時錯誤: 'document.getElementById(...)' 為空或不是對象”。這是什么原因呢?原來好好的,怎么套用個母版頁就出現(xiàn)這個奇怪的問題呢?困擾了好久,和朋友討論了一下,終于找到了答案……
三、分析本質(zhì)
原來我們仔細看看其生成的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="服務(wù)器端插入(_)" 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="服務(wù)器端插入(_)" 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都變了。那么我們?nèi)绾谓鉀Q它呢?既然他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"]鍵值需要改變,必須變?yōu)镽equest.Form["<%=txt.ClientID %>"]才能接收到頁面的值。想想如果想要得到ID的control是一個用戶控件的話,當(dāng)生成頁面后盡管能得到其ClientID,但是卻得不到這個對象,所以也就不能設(shè)置或獲得其屬性了。比如,我要做的這個用戶控件,由三個DropDownList組成,可是我卻想得到一個完整的日期值(指在客戶端),一種思路是先獲得三個DropDownList的ClientID,然后再由ID1.value+ID2.value+ID3.value取得,可是如果你一個頁面上需要放多個這樣的用戶控件的話,你需要取得多少個ClientID?顯然這樣做的話,工作量會很大,而且要操作眾多的對象,很容易出錯。
四、總結(jié)
這一類問題我像在我們編寫程序時往往經(jīng)常會遇到,總結(jié)一下:這應(yīng)該屬于“使用了MasterPage,或者GridView中的模版列后所有元素ID不一致問題”。由于種種原因(比如使用了MasterPage,或者GridView中的模版列),一個控件在設(shè)計時的ID往往不同于生成頁面后的ID,為了獲得控件客戶端ID,我們可以從生成的頁面入手,取控件id修改方法:
document.getElementById("ctl00$編輯區(qū)ID$控件ID"); document.getElementById("ctl00_編輯區(qū)ID_控件ID"); document.getElementById("<%=控件名ID.ClientID%>"); //推薦在我們設(shè)計時往往就會出現(xiàn)一些莫名其妙的問題,我想我們遇到問題時,冷靜思考,把握主次,從底層框架入手,糾其原因,相信最終會找到答案。
總結(jié)
以上是生活随笔為你收集整理的Tips/Tricks#0:母版页中对控件ID的处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [ASP.NET 控件实作 Day8]
- 下一篇: 有一段时间没来这里了,