要達到的目的很簡單:編寫一個使用者控制項,頁面載入時隱藏,當某個radioButton點擊時,顯示使用者控制項。但用起來卻發現不是那麼簡單。
錯誤方法一
首先想到的是最常用的方法,設定其Visible屬性為false:
<uc1:TGBDropDownList ID="TGBDropDownList2" runat="server" Visible ="false" />
點擊時出現:
<asp:RadioButton ID="radRecord" runat="server" Text="答題記錄" onclick="RadioRecordClick();" GroupName="QueryHistory" />
function RadioRecordClick() { document.getElementById("<%= TGBDropDownList2.ClientID%>").style.display = "inline"; }
出現錯誤
並且使用者控制項也並沒有隱藏:
如果希望開啟頁面時不顯示,不要使用visible=false,否則會指令碼會找不到控制項。
錯誤方法二
介面載入時隱藏:
<uc1:TGBDropDownList ID="TGBDropDownList2" runat="server" style="display:none;/>
當點擊RadioButton時顯示:
function RadioRecordClick() { document.getElementById("<%= radRecord.ClientID%>").style.display = "inline"; } <asp:RadioButton ID="radRecord" runat="server" Text="答題記錄" onclick="RadioRecordClick();" GroupName="QueryHistory" />
原因分析
結果和第一種方法一樣:使用者控制項並沒有隱藏,且出現"不能讀取空屬性style"的錯誤,可見即使使用style仍不能解決問題,為什嗎?
使用調試工具找到使用者控制項在用戶端的代碼:
<div> <span id="ContentPlaceHolder1_TGBDropDownList2_spanCollege"> 學院:<select name="ctl00$ContentPlaceHolder1$TGBDropDownList2$dropCollege" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$TGBDropDownList2$dropCollege\',\'\')', 0)" id="ContentPlaceHolder1_TGBDropDownList2_dropCollege" class="standardWidth1"><option value="87f8c14d-f244-4181-b277-066f0975ea74">生命科學學院</option><option value="9dbf5a3a-f01e-466d-ad53-53246dbe03df">數學與電腦科學學院</option><option value="a610a1fe-bdc1-442f-b637-f221d64f0d11">文學院</option><option value="d1ea12a9-9e52-4ce4-b271-2fd639de58d9">音樂學院</option><option value="f1767539-7ace-4761-8d70-3e98410c3702">體育學院</option><option value="f20e99a5-c63b-4740-bda1-34ec8d599bfc">外國語學院</option><option selected="selected" value="">請選擇</option></select> </span><span id="ContentPlaceHolder1_TGBDropDownList2_spanCourse"> 課程:<select name="ctl00$ContentPlaceHolder1$TGBDropDownList2$dropCourse" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$TGBDropDownList2$dropCourse\',\'\')', 0)" id="ContentPlaceHolder1_TGBDropDownList2_dropCourse" class="standardWidth1"><option selected="selected" value="">請選擇</option></select> </span><span id="ContentPlaceHolder1_TGBDropDownList2_spanExam"> 考試:<select name="ctl00$ContentPlaceHolder1$TGBDropDownList2$dropExam" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$TGBDropDownList2$dropExam\',\'\')', 0)" id="ContentPlaceHolder1_TGBDropDownList2_dropExam" class="standardWidth1"><option selected="selected" value="">請選擇</option></select> </span></div>
DOM結構
可見此使用者控制項被解析為的DOM樹為:
樣式屬性
即一個div下包含三個平行的span,再來看一下div和span所帶有的樣式屬性:
可見一是使用者控制項在用戶端解析後沒有ClientID只能算是一個匿名div,而且沒有可控制的display屬性。
解決方案
那怎麼解決使用者控制項的可見度問題?答案是Panel,把使用者控制項放到Panel控制項中,通過控制Panel的可見度間接控制使用者控制項的可見度。
隱藏使用者控制項代碼:
<br /> <asp:Panel ID="Panel1" runat="server" style="display:none;"> <uc1:TGBDropDownList ID="TGBDropDownList2" runat="server" /> </asp:Panel> <br />
顯示使用者控制項代碼:
<asp:RadioButton ID="radRecord" runat="server" Text="答題記錄" onclick="RadioRecordClick();" GroupName="QueryHistory" />
和
function RadioRecordClick() { document.getElementById("<%= Panel1.ClientID%>").style.display = "inline"; }
運行結果
介面載入時:
點擊答題記錄時:
DOM結構
解析的用戶端代碼:
<div id="ContentPlaceHolder1_Panel1" style="display: inline;"> <div> <span id="ContentPlaceHolder1_TGBDropDownList2_spanCollege"> 學院:<select name="ctl00$ContentPlaceHolder1$TGBDropDownList2$dropCollege" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$TGBDropDownList2$dropCollege\',\'\')', 0)" id="ContentPlaceHolder1_TGBDropDownList2_dropCollege" class="standardWidth1"><option value="87f8c14d-f244-4181-b277-066f0975ea74">生命科學學院</option><option value="9dbf5a3a-f01e-466d-ad53-53246dbe03df">數學與電腦科學學院</option><option value="a610a1fe-bdc1-442f-b637-f221d64f0d11">文學院</option><option value="d1ea12a9-9e52-4ce4-b271-2fd639de58d9">音樂學院</option><option value="f1767539-7ace-4761-8d70-3e98410c3702">體育學院</option><option value="f20e99a5-c63b-4740-bda1-34ec8d599bfc">外國語學院</option><option selected="selected" value="">請選擇</option></select> </span><span id="ContentPlaceHolder1_TGBDropDownList2_spanCourse"> 課程:<select name="ctl00$ContentPlaceHolder1$TGBDropDownList2$dropCourse" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$TGBDropDownList2$dropCourse\',\'\')', 0)" id="ContentPlaceHolder1_TGBDropDownList2_dropCourse" class="standardWidth1"><option selected="selected" value="">請選擇</option></select> </span><span id="ContentPlaceHolder1_TGBDropDownList2_spanExam"> 考試:<select name="ctl00$ContentPlaceHolder1$TGBDropDownList2$dropExam" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$TGBDropDownList2$dropExam\',\'\')', 0)" id="ContentPlaceHolder1_TGBDropDownList2_dropExam" class="standardWidth1"><option selected="selected" value="">請選擇</option></select> </span></div></div>
樣式屬性
對應的樣式屬性:
Panel控制項解析後用後ClientID及可控制display樣式屬性,所以能解決可見度的問題。