[ASP.net] 撰寫無障礙網頁的ASP.net技巧&分享
臺灣應該有不少Web開發者經常要撰寫行政院研考會規定的無障礙網頁
個人本身也常上網找ASP.net某個Server Control要如何撰寫才能通過無障礙標準,但這類文章很難找出個整理
所以此篇是獻給那些Web開發者們,在開發ASP.net程式時,有個參考指南(如果不曉得什麼是無障礙網頁,有興趣的人可以點選這裡)
本文以通過A+無障礙機器(FreeGo軟體掃描)檢測為主(以下簡稱A+)
要通過A+,跟ASP.net控制項有關的兩個原則:
1.<img />要有alt
2.各HTML Tag若有滑鼠事件,則要有對應的鍵盤事件
例如:onClick=>onKeyPress、onMouseOver=>onFocus、onMouseOut=>onBlur、onMouseDown=>onKeyDown、onMouseUp=>onKeyUp
看似簡單,但實際情況是,微軟有些控制項註定過不了無障礙標準或者加了AutoPostBack屬性後就無法通過
MSDN上針對無障礙網頁的一些說明:
ASP.NET 中的網頁可及性支援、ASP.NET 控制項和網頁可及性
以下針對常用到的ASP.net Server Control說明,呈現出HTML的Tag及該如何撰寫才能通過A+方法做些整理
(另外,講白一件事,能通過無障礙標準的網站,其實未必真的是無障礙網站XD)
文章很長,如果想快速5分鐘上手的話,建議速讀紅色部份就好,其他都是我在Try-Error證明該控制項過不過得了無障礙標準。
1. Label
ASP.net伺服器標記
<asp:Label ID="Label1" runat="server" Text="A" />
呈現的HTML
<span id="Label1">A</span>
2. Literal
ASP.net伺服器標記
<asp:Literal ID="Literal1" Text="A" runat="server" />
呈現的HTML:無
說明:如果一般要套美工人員版型的話,個人推薦用Literal,最能符合美工人員給的HTML版型
除非需要很多屬性輔助撰寫程式才用到Label,例如在GridView(或ListView)的資料繫結中,個人常會這樣寫
<asp:Label id=”lb_myLabel” runat=”server” Text=’<%# Eval(“欄位1”)%>’ ToolTip=’<%# Eval(“欄位2”)%>’ />
然後在GridView的RowDataBound事件,我就可以抓到該列欄位1和欄位2的值了。
這兩個控制項通常用來手寫HTML用,把握A+無障礙原則的話,要通過應該不難。
3. Image
ASP.net伺服器標記
<asp:Image ID="Image1" runat="server" AlternateText="必填alt" ImageUrl="images/Source.jpg" BorderWidth="0" />
呈現的HTML
<img id="Image1" src="images/Source.jpg" alt="必填alt" style="border-width:0px;" />
說明:要加上AlternateText屬性,才能通過。
如果要做滑鼠滑過置換圖片的效果,請參考以下寫法:
<asp:Image AlternateText="Alt必填" ImageUrl="原始圖片Url" onmouseout='this.src="原始圖片Url"' onblur='this.src="原始圖片Url"' onmouseover='this.src="置換圖片Url"' onfocus='this.src="置換圖片Url"' runat="server"/>
若在C# Code-Behind中,this.src=””雙引號要加 \ 跳脫字元。
2011.9.30 追加發現:即使沒有加BorderWidth屬性,呈現出的Html會加style="border-width:0px;"
4. HyperLink
ASP.net伺服器標記
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="http://www.google.com.tw" Target="_blank" Text="文字"
ToolTip="ToolTip會變成title">HyperLink Tag中間的文字</asp:HyperLink>
(像以上同時指定Text又Tag間包住文字,則Tag之間的文字會優先)
呈現的HTML
<a id="HyperLink1" title="ToolTip會變成title" href="http://www.google.com.tw" target="_blank">HyperLink Tag中間的文字</a>
說明:基本上可以通過A+,但該注意的是,不能加ImageUrl屬性,HyperLink的ToolTip呈現出HTML的為<a title=””></a>,如果指定了ImageUrl,就無法為那張圖片指定alt
所以想要超連結包住圖片,正確寫法:
<asp:HyperLink ID="lnk" NavigateUrl="Url位址" runat="server" >
<asp:Image ID="img" ImageUrl="圖片Url" AlternateText="圖片說明文字必填" runat="server" />
</asp:HyperLink>
或用Literal控制項手寫HTML
<a href="Url位址">
<img src="圖片Url" alt="圖片說明文字必填" />
</a>
5. DropDownList
說明:如果加上AutoPostBack屬性,則HTML Tag會多加onchange事件,不過仍可以通過A+,請安心服用。
呈現的HTML
<select name="DropDownList1" onchange="javascript:setTimeout('__doPostBack(\'DropDownList1\',\'\')', 0)" id="DropDownList1">
<option selected="selected" value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
</select>
6. RadioButton
ASP.net伺服器標記
<asp:RadioButton ID="rdo_A" Text="A" GroupName="group" runat="server" />
<asp:RadioButton ID="rdo_B" Text="B" GroupName="group" runat="server" />
呈現的HTML
<input id="rdo_A" type="radio" name="group" value="rdo_A" /><label for="rdo_A">A</label>
<input id="rdo_B" type="radio" name="group" value="rdo_B" /><label for="rdo_B">B</label>
若加上AutoPostBack屬性
<asp:RadioButton ID="rdo_A" Text="A" GroupName="group" AutoPostBack="true" runat="server" OnCheckedChanged="rdo_A_CheckedChanged" />
<asp:RadioButton ID="rdo_B" Text="B" GroupName="group" AutoPostBack="true" runat="server" OnCheckedChanged="rdo_B_CheckedChanged" />
呈現的HTML,<input>會自動加上onclick事件
<input id="rdo_A" type="radio" name="group" value="rdo_A" onclick="javascript:setTimeout('__doPostBack(\'rdo_A\',\'\')', 0)" /><label for="rdo_A">A</label>
<input id="rdo_B" type="radio" name="group" value="rdo_B" onclick="javascript:setTimeout('__doPostBack(\'rdo_B\',\'\')', 0)" /><label for="rdo_B">B</label>
嘗試為<input>加onkeypress鍵盤事件
protected void Page_Load(object sender, EventArgs e)
{
rdo_A.Attributes["onkeypress"] = "rdo_A_onkeypress();";
rdo_B.Attributes["onkeypress"] = "rdo_B_onkeypress();";
}
呈現的HTML
<span onkeypress="rdo_A_onkeypress();"><input id="rdo_A" type="radio" name="group" value="rdo_A" onclick="javascript:setTimeout('__doPostBack(\'rdo_A\',\'\')', 0)" /><label for="rdo_A">A</label></span>
<span onkeypress="rdo_B_onkeypress();"><input id="rdo_B" type="radio" name="group" value="rdo_B" onclick="javascript:setTimeout('__doPostBack(\'rdo_B\',\'\')', 0)" /><label for="rdo_B">B</label></span>
2011.7.2 追記 嘗試為<input>加onkeypress鍵盤事件
protected void Page_Load(object sender, EventArgs e)
{
rdo_A.InputAttributes["onkeypress"] = "rdo_A_onkeypress();";
rdo_B.InputAttributes["onkeypress"] = "rdo_B_onkeypress();";
}
呈現的HTML
<input id="rdo_A" type="radio" name="group" value="rdo_A" onclick="javascript:setTimeout('__doPostBack(\'rdo_A\',\'\')', 0)" onkeypress="rdo_A_onkeypress();" /><label for="rdo_A">A</label>
<input id="rdo_B" type="radio" name="group" value="rdo_B" onclick="javascript:setTimeout('__doPostBack(\'rdo_B\',\'\')', 0)" onkeypress="rdo_B_onkeypress();" /><label for="rdo_B">B</label>
結論:RadioButton加上AutoPostBack後,須在InputAttributes加上onkeypress事件才可過A+。
7. RadioButtonList
ASP.net伺服器標記
<asp:RadioButtonList ID="RadioButtonList1" runat="server">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>B</asp:ListItem>
<asp:ListItem>C</asp:ListItem>
</asp:RadioButtonList>
呈現的HTML
<table id="RadioButtonList1">
<tr>
<td><input id="RadioButtonList1_0" type="radio" name="RadioButtonList1" value="A" /><label for="RadioButtonList1_0">A</label></td>
</tr><tr>
<td><input id="RadioButtonList1_1" type="radio" name="RadioButtonList1" value="B" /><label for="RadioButtonList1_1">B</label></td>
</tr><tr>
<td><input id="RadioButtonList1_2" type="radio" name="RadioButtonList1" value="C" /><label for="RadioButtonList1_2">C</label></td>
</tr>
</table>
若加上AutoPostBack屬性
<asp:RadioButtonList ID="RadioButtonList1" runat="server" AutoPostBack="True"
onselectedindexchanged="RadioButtonList1_SelectedIndexChanged">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>B</asp:ListItem>
<asp:ListItem>C</asp:ListItem>
</asp:RadioButtonList>
呈現的HTML,<input>會自動加上onclick事件
<table id="RadioButtonList1" border="0">
<tr>
<td><input id="RadioButtonList1_0" type="radio" name="RadioButtonList1" value="A" onclick="javascript:setTimeout('__doPostBack(\'RadioButtonList1$0\',\'\')', 0)" /><label for="RadioButtonList1_0">A</label></td>
</tr><tr>
<td><input id="RadioButtonList1_1" type="radio" name="RadioButtonList1" value="B" onclick="javascript:setTimeout('__doPostBack(\'RadioButtonList1$1\',\'\')', 0)" /><label for="RadioButtonList1_1">B</label></td>
</tr>
<tr>
<td><input id="RadioButtonList1_2" type="radio" name="RadioButtonList1" value="C" onclick="javascript:setTimeout('__doPostBack(\'RadioButtonList1$2\',\'\')', 0)" /><label for="RadioButtonList1_2">C</label></td>
</tr>
</table>
嘗試為<input>加onkeypress鍵盤事件
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
RadioButtonList1.Attributes["onkeypress"] = "RadioButtonList1_onkeypress()";
foreach (ListItem item in RadioButtonList1.Items)
{
item.Attributes["onkeypress"] = "ListItem_onkeypress()";
}
}
}
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
{
}
呈現的HTML
<table id="RadioButtonList1" onkeypress="RadioButtonList1_onkeypress()" border="0">
<tr>
<td><span onkeypress="ListItem_onkeypress()"><input id="RadioButtonList1_0" type="radio" name="RadioButtonList1" value="A" onclick="javascript:setTimeout('__doPostBack(\'RadioButtonList1$0\',\'\')', 0)" /><label for="RadioButtonList1_0">A</label></span></td>
</tr>
<tr>
<td><span onkeypress="ListItem_onkeypress()"><input id="RadioButtonList1_1" type="radio" name="RadioButtonList1" value="B" onclick="javascript:setTimeout('__doPostBack(\'RadioButtonList1$1\',\'\')', 0)" /><label for="RadioButtonList1_1">B</label></span></td>
</tr>
<tr>
<td><span onkeypress="ListItem_onkeypress()"><input id="RadioButtonList1_2" type="radio" name="RadioButtonList1" value="C" onclick="javascript:setTimeout('__doPostBack(\'RadioButtonList1$2\',\'\')', 0)" /><label for="RadioButtonList1_2">C</label></span></td>
</tr>
</table>
2011.7.2追記,嘗試抓出RadioButtonList裡的Controls再加上InputAttributes
protected void Page_Load(object sender, EventArgs e)
{
foreach (Control c in RadioButtonList1.Controls)
{
((RadioButton)c).InputAttributes["onkeypress"] = "myKeyPress();";
}
}
呈現出的HTML
<table id="RadioButtonList1">
<tr>
<td><input id="RadioButtonList1_0" type="radio" name="RadioButtonList1" value="A" onclick="javascript:setTimeout('__doPostBack(\'RadioButtonList1$0\',\'\')', 0)" /><label for="RadioButtonList1_0">A</label></td>
</tr><tr>
<td><input id="RadioButtonList1_1" type="radio" name="RadioButtonList1" value="B" onclick="javascript:setTimeout('__doPostBack(\'RadioButtonList1$1\',\'\')', 0)" /><label for="RadioButtonList1_1">B</label></td>
</tr><tr>
<td><input id="RadioButtonList1_2" type="radio" name="RadioButtonList1" value="C" onclick="javascript:setTimeout('__doPostBack(\'RadioButtonList1$2\',\'\')', 0)" /><label for="RadioButtonList1_2">C</label></td>
</tr>
</table>
沒有出現myKeyPress();
結論:RadioButtonList預設可以通過A+,但加上AutoPostBack後因為onkeypress無法跟onclick在同一個Tag,所以會過不了A+。
RadioButtonList跟DropDownList同樣都是單選,如果需要AutoPostBack屬性來撈資料,可以考慮改用DropDownList替代。
8. CheckBox
ASP.net伺服器標記
<asp:CheckBox ID="CheckBox1" Text="A" runat="server" />
<asp:CheckBox ID="CheckBox2" Text="B" runat="server" />
呈現的HTML
<input id="CheckBox1" type="checkbox" name="CheckBox1" /><label for="CheckBox1">A</label>
<input id="CheckBox2" type="checkbox" name="CheckBox2" /><label for="CheckBox2">B</label>
若加上AutoPostBack屬性
<asp:CheckBox ID="CheckBox1" Text="A" runat="server" AutoPostBack="true" />
<asp:CheckBox ID="CheckBox2" Text="B" runat="server" AutoPostBack="true"/>
呈現的HTML,<input>會自動加上onclick事件
<input id="CheckBox1" type="checkbox" name="CheckBox1" onclick="javascript:setTimeout('__doPostBack(\'CheckBox1\',\'\')', 0)" /><label for="CheckBox1">A</label>
<input id="CheckBox2" type="checkbox" name="CheckBox2" onclick="javascript:setTimeout('__doPostBack(\'CheckBox2\',\'\')', 0)" /><label for="CheckBox2">B</label>
嘗試對CheckBox加入onkeypress
protected void Page_Load(object sender, EventArgs e)
{
CheckBox1.Attributes["onkeypress"] = "CheckBox1_onkeypress();";
CheckBox2.Attributes["onkeypress"] = "CheckBox2_onkeypress();";
}
呈現的HTML
<span onkeypress="CheckBox1_onkeypress();"><input id="CheckBox1" type="checkbox" name="CheckBox1" onclick="javascript:setTimeout('__doPostBack(\'CheckBox1\',\'\')', 0)" /><label for="CheckBox1">A</label></span>
<span onkeypress="CheckBox2_onkeypress();"><input id="CheckBox2" type="checkbox" name="CheckBox2" onclick="javascript:setTimeout('__doPostBack(\'CheckBox2\',\'\')', 0)" /><label for="CheckBox2">B</label></span>
2011.7.2 嘗試對CheckBox加入InputAttributes
protected void Page_Load(object sender, EventArgs e)
{
CheckBox1.InputAttributes["onkeypress"] = "CheckBox1_onkeypress();";
CheckBox2.InputAttributes["onkeypress"] = "CheckBox2_onkeypress();";
}
呈現出的HTML
<input id="CheckBox1" type="checkbox" name="CheckBox1" onclick="javascript:setTimeout('__doPostBack(\'CheckBox1\',\'\')', 0)" onkeypress="CheckBox1_onkeypress();" /><label for="CheckBox1">A</label>
<input id="CheckBox2" type="checkbox" name="CheckBox2" onclick="javascript:setTimeout('__doPostBack(\'CheckBox2\',\'\')', 0)" onkeypress="CheckBox2_onkeypress();" /><label for="CheckBox2">B</label>
結論:CheckBox加上AutoPostBack後,須加上InputAttributes才可過A+。
9. CheckBoxList
ASP.net伺服器標記
<asp:CheckBoxList ID="CheckBoxList1" runat="server">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>B</asp:ListItem>
</asp:CheckBoxList>
呈現的HTML
<table id="CheckBoxList1">
<tr>
<td><input id="CheckBoxList1_0" type="checkbox" name="CheckBoxList1$0" value="A" /><label for="CheckBoxList1_0">A</label></td>
</tr>
<tr>
<td><input id="CheckBoxList1_1" type="checkbox" name="CheckBoxList1$1" value="B" /><label for="CheckBoxList1_1">B</label></td>
</tr>
</table>
若加上AutoPostBack屬性
<asp:CheckBoxList ID="CheckBoxList1" runat="server" AutoPostBack="true">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>B</asp:ListItem>
</asp:CheckBoxList>
呈現的HTML,<input>會自動加上onclick事件
<table id="CheckBoxList1">
<tr>
<td><input id="CheckBoxList1_0" type="checkbox" name="CheckBoxList1$0" onclick="javascript:setTimeout('__doPostBack(\'CheckBoxList1$0\',\'\')', 0)" value="A" /><label for="CheckBoxList1_0">A</label></td>
</tr><tr>
<td><input id="CheckBoxList1_1" type="checkbox" name="CheckBoxList1$1" onclick="javascript:setTimeout('__doPostBack(\'CheckBoxList1$1\',\'\')', 0)" value="B" /><label for="CheckBoxList1_1">B</label></td>
</tr>
</table>
嘗試對CheckBoxList加入onkeypress
protected void Page_Load(object sender, EventArgs e)
{
CheckBoxList1.Attributes["onkeypress"] = "CheckBoxList1_onkeypress()";
foreach (ListItem item in CheckBoxList1.Items)
{
item.Attributes["onkeypress"] = "item_onkeypress();";
}
}
呈現的HTML
<table id="CheckBoxList1" onkeypress="CheckBoxList1_onkeypress()">
<tr>
<td><span onkeypress="item_onkeypress();"><input id="CheckBoxList1_0" type="checkbox" name="CheckBoxList1$0" onclick="javascript:setTimeout('__doPostBack(\'CheckBoxList1$0\',\'\')', 0)" value="A" /><label for="CheckBoxList1_0">A</label></span></td>
</tr><tr>
<td><span onkeypress="item_onkeypress();"><input id="CheckBoxList1_1" type="checkbox" name="CheckBoxList1$1" onclick="javascript:setTimeout('__doPostBack(\'CheckBoxList1$1\',\'\')', 0)" value="B" /><label for="CheckBoxList1_1">B</label></span></td>
</tr>
</table>
2011.7.2嘗試對CheciBoxList裡的每個CheckBox加上InputAttributes
protected void Page_Load(object sender, EventArgs e)
{
foreach (Control c in CheckBoxList1.Controls)
{
((CheckBox)c).InputAttributes["onkeypress"] = "item_onkeypress();";
}
}
呈現的HTML
<table id="CheckBoxList1">
<tr>
<td><input id="CheckBoxList1_0" type="checkbox" name="CheckBoxList1$0" onclick="javascript:setTimeout('__doPostBack(\'CheckBoxList1$0\',\'\')', 0)" onkeypress="item_onkeypress();" value="A" /><label for="CheckBoxList1_0">A</label></td>
</tr><tr>
<td><input id="CheckBoxList1_1" type="checkbox" name="CheckBoxList1$1" onclick="javascript:setTimeout('__doPostBack(\'CheckBoxList1$1\',\'\')', 0)" onkeypress="item_onkeypress();" value="B" /><label for="CheckBoxList1_1">B</label></td>
</tr>
</table>
結論:CheckBoxList加上AutoPostBack後須加上InputAttributes才可過A+。
2011.11.09 追記
RepeatLayout=”Flow”
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatLayout="Flow">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>B</asp:ListItem>
<asp:ListItem>C</asp:ListItem>
</asp:CheckBoxList>
呈現的Html(容器為span、換行使用<br/>)
<span id="Span1">
<input id="CheckBoxList1_0" type="checkbox" name="CheckBoxList1$0" value="A" /><label
for="CheckBoxList1_0">A</label><br />
<input id="CheckBoxList1_1" type="checkbox" name="CheckBoxList1$1" value="B" /><label
for="CheckBoxList1_1">B</label><br />
<input id="CheckBoxList1_2" type="checkbox" name="CheckBoxList1$2" value="C" /><label
for="CheckBoxList1_2">C</label>
</span>
RepeatLayout=”UnorderedList”
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatLayout="UnorderedList">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>B</asp:ListItem>
<asp:ListItem>C</asp:ListItem>
</asp:CheckBoxList>
呈現的Html(容器為ul、每個項目為li)
<ul id="CheckBoxList1">
<li><input id="CheckBoxList1_0" type="checkbox" name="CheckBoxList1$0" value="A" /><label for="CheckBoxList1_0">A</label></li>
<li><input id="CheckBoxList1_1" type="checkbox" name="CheckBoxList1$1" value="B" /><label for="CheckBoxList1_1">B</label></li>
<li><input id="CheckBoxList1_2" type="checkbox" name="CheckBoxList1$2" value="C" /><label for="CheckBoxList1_2">C</label></li>
</ul>
RepeatLayout=”OrderedList”
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatLayout="OrderedList">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>B</asp:ListItem>
<asp:ListItem>C</asp:ListItem>
</asp:CheckBoxList>
呈現的Html(容器為ol、每個項目為li)
<ol id="CheckBoxList1">
<li><input id="CheckBoxList1_0" type="checkbox" name="CheckBoxList1$0" value="A" /><label for="CheckBoxList1_0">A</label></li>
<li><input id="CheckBoxList1_1" type="checkbox" name="CheckBoxList1$1" value="B" /><label for="CheckBoxList1_1">B</label></li>
<li><input id="CheckBoxList1_2" type="checkbox" name="CheckBoxList1$2" value="C" /><label for="CheckBoxList1_2">C</label></li>
</ol>
CheckBoxList預設的RepeatLayout為Table
10. ListBox
ASP.net伺服器標記
<asp:ListBox ID="ListBox1" runat="server">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>B</asp:ListItem>
<asp:ListItem>C</asp:ListItem>
</asp:ListBox>
呈現的HTML
<select size="4" name="ListBox1" id="ListBox1">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
若加上AutoPostBack屬性
<asp:ListBox ID="ListBox1" runat="server" AutoPostBack="true">
<asp:ListItem>A</asp:ListItem>
<asp:ListItem>B</asp:ListItem>
<asp:ListItem>C</asp:ListItem>
</asp:ListBox>
呈現的HTML
<select size="4" name="ListBox1" onchange="javascript:setTimeout('__doPostBack(\'ListBox1\',\'\')', 0)" id="ListBox1">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
多選的HTML
<select size="4" name="ListBox1" multiple="multiple" onchange="javascript:setTimeout('__doPostBack(\'ListBox1\',\'\')', 0)" id="ListBox1">
<option selected="selected" value="A">A</option>
<option selected="selected" value="B">B</option>
<option selected="selected" value="C">C</option>
</select>
結論:不管單選還是多選,ListBox都可以過A+,請安心服用。
11. TextBox
ASP.net伺服器標記
<asp:TextBox ID="TextBox1" Text="A" runat="server" />
呈現的HTML
<input name="TextBox1" type="text" value="A" id="TextBox1" />
2011.7.2 追記:加上AutoPostBack
<asp:TextBox ID="TextBox1" Text="A" runat="server" AutoPostBack="True" ontextchanged="TextBox1_TextChanged" />
呈現的HTML
<input name="TextBox1" type="text" value="A" onchange="javascript:setTimeout('__doPostBack(\'TextBox1\',\'\')', 0)" onkeypress="if (WebForm_TextBoxKeyHandler(event) == false) return false;" id="TextBox1" />
結論:TextBox可以過A+
12. Button
2011.12.03 修改
ASP.net伺服器標記
<!--UseSubmitBehavior預設"true"-->
<asp:Button runat="server" ID="btn_submit" Text="我是submit"
onclick="btn_submit_Click" />
<asp:Button runat="server" ID="btn" Text="我是真Button" UseSubmitBehavior="false"
onclick="btn_Click" />
呈現的HTML
<!--UseSubmitBehavior預設"true"-->
<input type="submit" name="btn_submit" value="我是submit" id="btn_submit" />
<input type="button" name="btn" value="我是真Button" onclick="javascript:__doPostBack('btn','')" id="btn" />
在設計畫面就加上onkeypress
<!--UseSubmitBehavior預設"true"-->
<asp:Button runat="server" ID="btn_submit" Text="我是submit" onkeypress=""
onclick="btn_submit_Click" />
<asp:Button runat="server" ID="btn" Text="我是真Button" UseSubmitBehavior="false" onkeypress=""
onclick="btn_Click" />
<!--onkeypress不給值,才能真正用鍵盤觸發Server端事件-->
呈現的HTML
<!--UseSubmitBehavior預設"true"-->
<input type="submit" name="btn_submit" value="我是submit" id="btn_submit" onkeypress="" />
<input type="button" name="btn" value="我是真Button" onclick="javascript:__doPostBack('btn','')" id="btn" onkeypress="" />
結論:最好加上onkeypress(不給值)安心過A+檢測。
13. ImageButton
通常會搭配做滑鼠移過置換圖片效果,請參考以下寫法
ASP.net伺服器標記
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="images/Source.jpg"
onmouseout='this.src="images/Source.jpg"'
onblur='this.src="images/Source.jpg"'
onmouseover='this.src="images/MouseOver.jpg"'
onfocus='this.src="images/MouseOver.jpg"'
AlternateText="必填alt"
OnClick="ImageButton1_Click"
onkeypress="ImageButton1_Click" />
呈現的HTML
<input type="image" name="ImageButton1" id="ImageButton1" onmouseout="this.src="images/Source.jpg"" onblur="this.src="images/Source.jpg"" onmouseover="this.src="images/MouseOver.jpg"" onfocus="this.src="images/MouseOver.jpg"" onkeypress="ImageButton1_Click" src="images/Source.jpg" alt="必填alt" style="border-width:0px;" />
結論:要加AlternateText和onkeypress就可以過A+。
2011.9.30 追加發現:即使沒有加BorderWidth屬性,呈現出的Html會加style="border-width:0px;"
14 LinkButton
ASP.net伺服器標記
<asp:LinkButton ID="LinkButton1" Text="A" runat="server" onclick="LinkButton1_Click" />
呈現的HTML
<a id="LinkButton1" href="javascript:__doPostBack('LinkButton1','')">A</a>
結論:因為是href=”javascript:__doPostBack();”,所以確定不用加onkeypress就可以過A+。
題外話,若這樣寫的話
<asp:LinkButton ID="LinkButton" Text="A" runat="server" onclick="LinkButton_Click" >
<img border="0" src="images/Source.jpg" alt="必填" />
</asp:LinkButton>
呈現的HTML
<a id="LinkButton" href="javascript:__doPostBack('LinkButton','')">
<img border="0" src="images/Source.jpg" alt="必填" />
</a>
操作起來感覺像ImageButton,實際上內容是超連結包圖片
15. FileUpload
ASP.net伺服器標記
<asp:FileUpload ID="FileUpload1" runat="server"/>
呈現的HTML
<input type="file" name="FileUpload1" id="FileUpload1" />
結論:沒什麼特別設定,可以過A+。
16. MultiView
17. View
ASP.net伺服器標記
<asp:MultiView ID="MultiView1" runat="server" onactiveviewchanged="MultiView1_ActiveViewChanged">
<asp:View ID="View1" runat="server">
A
</asp:View>
<asp:View ID="View2" runat="server">
B
</asp:View>
</asp:MultiView>
呈現的HTML:無
結論:MultiView和View都是空白的Container,因為無HTML Tag,當然也就可以通過A+。
18. Panel
ASP.net伺服器標記
<asp:Panel ID="Panel1" runat="server">
A
</asp:Panel>
呈現的HTML
<div id="Panel1">
A
</div>
結論:Panel是HTML <div>的Container,可以通過A+。
19. PlaceHolder
ASP.net伺服器標記
<asp:PlaceHolder ID="PlaceHolder1" runat="server">
A
</asp:PlaceHolder>
呈現的HTML:無
說明:因為是沒有HTML Tag的Container,可以通過A+
為了避免破壞美工人員的版型,我自己也常使用PlaceHolder取代Panel,兩者在使用上大同小異。
20. Menu
ASP.net伺服器標記
<asp:Menu ID="Menu1" runat="server">
<Items>
<asp:MenuItem Text="A" Value="A"></asp:MenuItem>
<asp:MenuItem Text="B" Value="B"></asp:MenuItem>
<asp:MenuItem Text="C" Value="C"></asp:MenuItem>
</Items>
</asp:Menu>
呈現的HTML,<a>會自動加onclick事件
<a href="#Menu1_SkipLink"><img alt="略過巡覽連結" src="/testAplus/WebResource.axd?d=ZyICRpmMjOQ_uiS7ICGIGYp-6b6UuePx1mwIUPlSBP_iZvPepn-QpGwoAXemYK27AzmqKkdmsJk9M-wHDAhqTRvu5V_SPOcsqjfGELKzMLA1&t=634402701822635329" width="0" height="0" style="border-width:0px;" /></a>
<div id="Menu1">
<ul class="level1">
<li><a class="level1 selected" href="#" onclick="__doPostBack('Menu1','A')">A</a></li>
<li><a class="level1" href="#" onclick="__doPostBack('Menu1','B')">B</a></li>
<li><a class="level1" href="#" onclick="__doPostBack('Menu1','C')">C</a></li>
</ul>
</div><a id="Menu1_SkipLink"></a>
嘗試為<a>加onkeypress,MenuItem無法加Attributes
所以用Menu直接加Attributes["onkeypress"]試試看
呈現的HTML
<a href="#Menu1_SkipLink"><img alt="略過巡覽連結" src="/testAplus/WebResource.axd?d=ZyICRpmMjOQ_uiS7ICGIGYp-6b6UuePx1mwIUPlSBP_iZvPepn-QpGwoAXemYK27AzmqKkdmsJk9M-wHDAhqTRvu5V_SPOcsqjfGELKzMLA1&t=634402701822635329" width="0" height="0" style="border-width:0px;" /></a>
<div onkeypress="Menu1_onkeypress();" id="Menu1">
<ul class="level1">
<li><a class="level1 selected" href="#" onclick="__doPostBack('Menu1','A')">A</a></li>
<li><a class="level1" href="#" onclick="__doPostBack('Menu1','B')">B</a></li>
<li><a class="level1" href="#" onclick="__doPostBack('Menu1','C')">C</a></li>
</ul>
</div><a id="Menu1_SkipLink"></a>
結果onkeypress並不是加在和onclick同一個Tag中,而是加在<div>
改用修改樣版的方式,只會變成
<li><a class="level1" href="#" onclick="__doPostBack('Menu1','A')">
超連結包起來的文字
</a>
</li>
結論:Menu無法通過A+,須改用jQuery UI的替代方案
38 jQuery And CSS Drop Down Multi Level Menu Solutions
10 Best jQuery Menu Plugins – AjaxLine
25 jQuery Drop Down Menu Scripts Vandelay Design Blog
2012.9.14 追記:MSDN有人提出解法,override Page的Render,說不定TreeView也可以依樣畫蘆?
ASP.NET 的 Menu 控制項 無法在 Android 上運作(黃小榮)
21. TreeView
ASP.net伺服器標記
<asp:TreeView ID="TreeView1" runat="server" >
<Nodes>
<asp:TreeNode Text="A" Value="A" >
<asp:TreeNode Text="A-1" Value="A-1"></asp:TreeNode>
</asp:TreeNode>
</Nodes>
</asp:TreeView>
呈現的HTML,A和A-1節點所在的超連結被自動加onclick事件
<a href="#TreeView1_SkipLink"><img alt="略過巡覽連結。" src="/testAplus/WebResource.axd?d=ZyICRpmMjOQ_uiS7ICGIGYp-6b6UuePx1mwIUPlSBP_iZvPepn-QpGwoAXemYK27AzmqKkdmsJk9M-wHDAhqTRvu5V_SPOcsqjfGELKzMLA1&t=634402701822635329" width="0" height="0" style="border-width:0px;" /></a>
<div id="TreeView1">
<table cellpadding="0" cellspacing="0" style="border-width:0;">
<tr>
<td><a id="TreeView1n0" href="javascript:TreeView_ToggleNode(TreeView1_Data,0,TreeView1n0,' ',TreeView1n0Nodes)"><img src="/testAplus/WebResource.axd?d=cMkl8rKLA1w_DOHuoXhUFRWuNhmJjN0XPq8umq0y2M0T8ZKcqiICXVG7lLeUAbDbSYGZEF5I8umpJx_5y_8NN5_jjYEVLY6AE3fQf724xo7ciZZdjnZwMfiB1w_TUibS0&t=634402701822635329" alt="摺疊 A" style="border-width:0;" /></a></td>
<td style="white-space:nowrap;"><a class="TreeView1_0" href="javascript:__doPostBack('TreeView1','sA')" onclick="TreeView_SelectNode(TreeView1_Data, this,'TreeView1t0');" id="TreeView1t0">A</a></td>
</tr>
</table><div id="TreeView1n0Nodes" style="display:block;">
<table cellpadding="0" cellspacing="0" style="border-width:0;">
<tr>
<td><div style="width:20px;height:1px"></div></td>
<td><img src="/testAplus/WebResource.axd?d=IVsTWyp_B_x6D1UPog_gzdmCyT44_Dbztc8veURgOJ2T29n6-Wy4uyrCk8TkxxlZ69Vk5vR0anoELYQBWadwdaVWh4bWLtVEdm_tlCGWXQsKi4cIe1QqRTDiQNp2Pw7q0&t=634402701822635329" alt="" /></td>
<td style="white-space:nowrap;"><a class="TreeView1_0" href="javascript:__doPostBack('TreeView1','sA\\A-1')" onclick="TreeView_SelectNode(TreeView1_Data, this,'TreeView1t1');" id="TreeView1t1">A-1</a></td>
</tr>
</table>
</div>
</div><a id="TreeView1_SkipLink"></a>
嘗試加入onkeypress
TreeNode無法加入Attributes,所以用TreeView直接加Attributes["onkeypress"]試試看
呈現的HTML
<a href="#TreeView1_SkipLink"><img alt="略過巡覽連結。" src="/testAplus/WebResource.axd?d=ZyICRpmMjOQ_uiS7ICGIGYp-6b6UuePx1mwIUPlSBP_iZvPepn-QpGwoAXemYK27AzmqKkdmsJk9M-wHDAhqTRvu5V_SPOcsqjfGELKzMLA1&t=634402701822635329" width="0" height="0" style="border-width:0px;" /></a>
<div id="TreeView1" onkeypress="TreeView1_onkeypress();">
<table cellpadding="0" cellspacing="0" style="border-width:0;">
<tr>
<td><a id="TreeView1n0" href="javascript:TreeView_ToggleNode(TreeView1_Data,0,TreeView1n0,' ',TreeView1n0Nodes)"><img src="/testAplus/WebResource.axd?d=cMkl8rKLA1w_DOHuoXhUFRWuNhmJjN0XPq8umq0y2M0T8ZKcqiICXVG7lLeUAbDbSYGZEF5I8umpJx_5y_8NN5_jjYEVLY6AE3fQf724xo7ciZZdjnZwMfiB1w_TUibS0&t=634402701822635329" alt="摺疊 A" style="border-width:0;" /></a></td>
<td style="white-space:nowrap;"><a class="TreeView1_0" href="javascript:__doPostBack('TreeView1','sA')" onclick="TreeView_SelectNode(TreeView1_Data, this,'TreeView1t0');" id="TreeView1t0">A</a></td>
</tr>
</table><div id="TreeView1n0Nodes" style="display:block;">
<table cellpadding="0" cellspacing="0" style="border-width:0;">
<tr>
<td><div style="width:20px;height:1px"></div></td>
<td><img src="/testAplus/WebResource.axd?d=IVsTWyp_B_x6D1UPog_gzdmCyT44_Dbztc8veURgOJ2T29n6-Wy4uyrCk8TkxxlZ69Vk5vR0anoELYQBWadwdaVWh4bWLtVEdm_tlCGWXQsKi4cIe1QqRTDiQNp2Pw7q0&t=634402701822635329" alt="" /></td>
<td style="white-space:nowrap;"><a class="TreeView1_0" href="javascript:__doPostBack('TreeView1','sA\\A-1')" onclick="TreeView_SelectNode(TreeView1_Data, this,'TreeView1t1');" id="TreeView1t1">A-1</a></td>
</tr>
</table>
</div>
</div><a id="TreeView1_SkipLink"></a>
結果onkeypress加在<div>並不是加在和onclick同一個<a>中
結論:TreeView無法通過A+,須改用jQuery UI的替代方案 ,例如:jQuery TreeView
22. Chart
ASP.net伺服器標記
<asp:SqlDataSource runat="server" id="sds_test"
ConnectionString="<%$ ConnectionStrings:NorthwindChineseConnectionString %>"
SelectCommand="Select CategoryID,count(*) as 筆數
From Products
Group by CategoryID"/>
/*******************************************************************/
<asp:Chart ID="Chart1" runat="server" DataSourceID="sds_test"
AlternateText="alt必填">
<Series>
<asp:Series Name="Series1" XValueMember="CategoryID" YValueMembers="筆數" >
</asp:Series>
</Series>
<ChartAreas>
<asp:ChartArea Name="ChartArea1">
</asp:ChartArea>
</ChartAreas>
</asp:Chart>
呈現的HTML
分三種RenderType
使用預設的ImageTag
<img id="Chart1" src="/testAplus/ChartImg.axd?i=chart_964cd50b67a1455a94fb49e9fe580d12_1.png&g=60e0a262db354e63a63594591355fb4f" alt="alt必填" style="height:300px;width:300px;border-width:0px;" />
結論:RenderType使用預設的ImageTag,Chart須加AlternateText
若RenderType使用ImageMap的HTML情況
<img id="Chart1" src="ChartPic_#SEQ(300,3)?4f1ca5fd-818e-4380-97e7-cbe339819138" alt="alt必填" usemap="#Chart1ImageMap" style="height:300px;width:300px;border-width:0px;" />
<map name="Chart1ImageMap" id="Chart1ImageMap">
<area shape="rect" coords="0,0,0,0" alt="" />
</map>
<map>裡面的<area alt="" />無疑是給自己找麻煩
23. Calendar
ASP.net伺服器標記
<asp:Calendar ID="Calendar1" runat="server"></asp:Calendar>
呈現的HTML
<table id="Calendar1" cellspacing="0" cellpadding="2" title="Calendar" border="0" style="border-width:1px;border-style:solid;border-collapse:collapse;">
<tr><td colspan="7" style="background-color:Silver;"><table cellspacing="0" border="0" style="width:100%;border-collapse:collapse;">
<tr><td style="width:15%;"><a href="javascript:__doPostBack('Calendar1','V4108')" style="color:Black" title="Go to the previous month"><</a></td><td align="center" style="width:70%;">2011年5月</td><td align="right" style="width:15%;"><a href="javascript:__doPostBack('Calendar1','V4169')" style="color:Black" title="Go to the next month">></a></td></tr>
</table></td></tr><tr><th align="center" abbr="星期日" scope="col">週日</th><th align="center" abbr="星期一" scope="col">週一</th><th align="center" abbr="星期二" scope="col">週二</th><th align="center" abbr="星期三" scope="col">週三</th><th align="center" abbr="星期四" scope="col">週四</th><th align="center" abbr="星期五" scope="col">週五</th><th align="center" abbr="星期六" scope="col">週六</th></tr><tr><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4131')" style="color:Black" title="4月24日">24</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4132')" style="color:Black" title="4月25日">25</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4133')" style="color:Black" title="4月26日">26</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4134')" style="color:Black" title="4月27日">27</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4135')" style="color:Black" title="4月28日">28</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4136')" style="color:Black" title="4月29日">29</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4137')" style="color:Black" title="4月30日">30</a></td></tr><tr><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4138')" style="color:Black" title="5月1日">1</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4139')" style="color:Black" title="5月2日">2</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4140')" style="color:Black" title="5月3日">3</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4141')" style="color:Black" title="5月4日">4</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4142')" style="color:Black" title="5月5日">5</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4143')" style="color:Black" title="5月6日">6</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4144')" style="color:Black" title="5月7日">7</a></td></tr><tr><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4145')" style="color:Black" title="5月8日">8</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4146')" style="color:Black" title="5月9日">9</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4147')" style="color:Black" title="5月10日">10</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4148')" style="color:Black" title="5月11日">11</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4149')" style="color:Black" title="5月12日">12</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4150')" style="color:Black" title="5月13日">13</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4151')" style="color:Black" title="5月14日">14</a></td></tr><tr><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4152')" style="color:Black" title="5月15日">15</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4153')" style="color:Black" title="5月16日">16</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4154')" style="color:Black" title="5月17日">17</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4155')" style="color:Black" title="5月18日">18</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4156')" style="color:Black" title="5月19日">19</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4157')" style="color:Black" title="5月20日">20</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4158')" style="color:Black" title="5月21日">21</a></td></tr><tr><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4159')" style="color:Black" title="5月22日">22</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4160')" style="color:Black" title="5月23日">23</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4161')" style="color:Black" title="5月24日">24</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4162')" style="color:Black" title="5月25日">25</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4163')" style="color:Black" title="5月26日">26</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4164')" style="color:Black" title="5月27日">27</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4165')" style="color:Black" title="5月28日">28</a></td></tr><tr><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4166')" style="color:Black" title="5月29日">29</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4167')" style="color:Black" title="5月30日">30</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4168')" style="color:Black" title="5月31日">31</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4169')" style="color:Black" title="6月1日">1</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4170')" style="color:Black" title="6月2日">2</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4171')" style="color:Black" title="6月3日">3</a></td><td align="center" style="width:14%;"><a href="javascript:__doPostBack('Calendar1','4172')" style="color:Black" title="6月4日">4</a></td></tr>
</table>
結論:因為可以按的部份都是href=”javascript:__doPostBack();”,所以不用加onkeypress就可以過A+。
24. ImageMap
說明:
請美工人員用Dreamweaver切<map > <area alt="alt必填"></map>來替代此控制項。
25. GridView
ASP.net伺服器標記(加入排序和分頁)
<asp:SqlDataSource runat="server" ID="sds_test"
ConnectionString="<%$ ConnectionStrings:NorthwindChineseConnectionString %>"
SelectCommand="SELECT [ProductID], [ProductName] FROM [Products]" />
/**********************************************************************/
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="ProductID"
DataSourceID="sds_test">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
</Columns>
</asp:GridView>
呈現的HTML
<table cellspacing="0" rules="all" border="1" id="GridView1" style="border-collapse:collapse;">
<tr>
<th scope="col"><a href="javascript:__doPostBack('GridView1','Sort$ProductID')">ProductID</a></th><th scope="col"><a href="javascript:__doPostBack('GridView1','Sort$ProductName')">ProductName</a></th>
</tr><tr>
<td>1</td><td>蘋果汁</td>
</tr><tr>
<td>2</td><td>牛奶</td>
</tr><tr>
<td>3</td><td>蕃茄醬</td>
</tr><tr>
<td>4</td><td>鹽巴</td>
</tr><tr>
<td>5</td><td>麻油</td>
</tr><tr>
<td>6</td><td>醬油</td>
</tr><tr>
<td>7</td><td>海鮮粉</td>
</tr><tr>
<td>8</td><td>胡椒粉</td>
</tr><tr>
<td>9</td><td>讚油雞</td>
</tr><tr>
<td>10</td><td>大甲蟹</td>
</tr><tr>
<td colspan="2"><table>
<tr>
<td><span>1</span></td><td><a href="javascript:__doPostBack('GridView1','Page$2')">2</a></td><td><a href="javascript:__doPostBack('GridView1','Page$3')">3</a></td><td><a href="javascript:__doPostBack('GridView1','Page$4')">4</a></td><td><a href="javascript:__doPostBack('GridView1','Page$5')">5</a></td><td><a href="javascript:__doPostBack('GridView1','Page$6')">6</a></td><td><a href="javascript:__doPostBack('GridView1','Page$7')">7</a></td><td><a href="javascript:__doPostBack('GridView1','Page$8')">8</a></td>
</tr>
</table></td>
</tr>
</table>
結論:排序和分頁,可以按的部份都是href=”javascript:__doPostBack();”,所以不用加onkeypress就可以過A+。
2011.11.26 追記
<table>外面其實還有一個<div>來包住此<table>...</table>
26. ListView
ASP.net伺服器標記(加入分頁功能)
<asp:SqlDataSource runat="server" ID="sds_test" ConnectionString="<%$ ConnectionStrings:NorthwindChineseConnectionString %>"
SelectCommand="SELECT [ProductID], [ProductName] FROM [Products]" />
/***********************************************************************************************************/
<asp:ListView ID="ListView1" runat="server" DataKeyNames="ProductID" DataSourceID="sds_test">
<ItemTemplate>
<tr style="">
<td>
<asp:Label ID="ProductIDLabel" runat="server" Text='<%# Eval("ProductID") %>' />
</td>
<td>
<asp:Label ID="ProductNameLabel" runat="server" Text='<%# Eval("ProductName") %>' />
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" border="0" style="">
<tr runat="server" style="">
<th runat="server">
ProductID
</th>
<th runat="server">
ProductName
</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
<tr>
<td>
<asp:DataPager ID="DataPager1" runat="server">
<Fields>
<asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="True" ShowNextPageButton="False"
ShowPreviousPageButton="False" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField ButtonType="Link" ShowLastPageButton="True" ShowNextPageButton="False"
ShowPreviousPageButton="False" />
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
主要注意DataPager的PagerField,ButtonType有三種:Button、Link、Image
Button呈現的HTML
<span id="ListView1_DataPager1">
<input type="submit" name="ListView1$DataPager1$ctl00$ctl00" value="First" disabled="disabled" />
<span>1</span>
<a href="javascript:__doPostBack('ListView1$DataPager1$ctl01$ctl01','')">2</a>
<a href="javascript:__doPostBack('ListView1$DataPager1$ctl01$ctl02','')">3</a>
<input type="submit" name="ListView1$DataPager1$ctl02$ctl00" value="Last" />
</span>
<input>沒有被加onclick,所以無需加onkeypress
Link呈現的HTML
<span id="ListView1_DataPager1">
<a class="aspNetDisabled">第一頁</a>
<span>1</span>
<a href="javascript:__doPostBack('ListView1$DataPager1$ctl01$ctl01','')">2</a>
<a href="javascript:__doPostBack('ListView1$DataPager1$ctl01$ctl02','')">3</a>
<a href="javascript:__doPostBack('ListView1$DataPager1$ctl02$ctl00','')">最後一頁</a>
</span>
Image呈現的HTML(<input>會被自動加alt說明文字)
<span id="ListView1_DataPager1">
<input type="image" name="ListView1$DataPager1$ctl00$ctl00" disabled="disabled" src="images/Source.jpg" alt="First" style="border-width:0px;" />
<span>1</span>
<a href="javascript:__doPostBack('ListView1$DataPager1$ctl01$ctl01','')">2</a>
<a href="javascript:__doPostBack('ListView1$DataPager1$ctl01$ctl02','')">3</a>
<input type="image" name="ListView1$DataPager1$ctl02$ctl00" src="images/Source.jpg" alt="Last" style="border-width:0px;" />
</span>
說明:DataPager的三種ButtonType,經過機器檢測都可以通過A+,不過畢竟Button和Image呈現出來的是input,難保不會有狀況
這時須改用Link的ButtonType或手寫自訂分頁
27. Silverlight、Flash、Media Player的<object>、<iframe>
拿Silverlight當範例,</object>前面要有說明文字,<iframe>屬性要加title
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/testSilverlightObject.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="4.0.50826.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
這是Silverlight應用程式
</object>
<iframe title="iframe要加title" id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe>
</div>
2011.5.31 追記,</object>前面的說明文字在Firefox上瀏覽的話會直接顯示該說明文字,所以改成以下寫法也可以過無障礙
這是Silverlight應用程式 ↓
<span style="display:none;">這是Silverlight應用程式</span>
28. UpdatePanel
<!--ScriptManager位置-->
<asp:ScriptManager runat="server" />
<!--Timer位置-->
<asp:Timer ID="Timer1" runat="server" Interval="1000" />
<!--UpdatePanel位置-->
<asp:UpdatePanel runat="server" ID="UpdatePanel1" UpdateMode="Conditional">
<ContentTemplate>
<!--Literal位置-->
<asp:Literal id="li_Text" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
</asp:UpdatePanel>
呈現結果
<!--Timer位置-->
<span id="Timer1" style="visibility:hidden;display:none;"></span>
<!--UpdatePanel位置-->
<div id="UpdatePanel1">
<!--Literal位置-->
</div>
結論:UpdatePanel呈現出來的只是<div>,可以通過A+
29. 驗證控制項
<form id="form1" runat="server">
<asp:TextBox runat="server" ID="txt_TextBox" />
<!--RequiredFieldValidator1,Display設成None的話,呈現出Html style為display:none;驗證不通過也不顯示-->
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ErrorMessage="TextBox必填" ControlToValidate="txt_TextBox"
runat="server" Display="None" />
<!--RequiredFieldValidator2 Display預設Static-->
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" Display="Static"
ErrorMessage="TextBox必填" ControlToValidate="txt_TextBox"
runat="server" />
<!--RequiredFieldValidator3 Display設成Dynamic的話,呈現出Html style為display:none;-->
<asp:RequiredFieldValidator ID="RequiredFieldValidator3"
ErrorMessage="TextBox必填" ControlToValidate="txt_TextBox"
runat="server" Display="Dynamic" />
<asp:Button Text="提交" ID="btn_submit" runat="server" />
</form>
執行呈現結果Html
驗證控制項呈現出來的都是span,可以過A+
但要注意Display屬性設成Static(visibility:hidden)和Dynamic(display:none)的差別
<asp:ValidationSummary ID="ValidationSummary1" runat="server" />
ValidationSummary控制項呈現出的Html
<div id="ValidationSummary1" style="color:Red;display:none;">
ValidationSummary呈現出div,可以過A+
30. 其他
通常jQuery UI Plugin一定過得了A+,因為那些滑鼠事件都寫在Javascript裡,HTML部份機器是掃不出來
所以若有遇到過不了無障礙的控制項,或不曉得該控制項如何加鍵盤事件的話,可以考慮使用jQuery UI Plugin
最後提供一個通過AA無障礙網頁標準的技巧
AA無障礙網頁最令人頭痛的是任何Tag的大小都不能用絕對像素,必須用百分比來顯示
例如:<table width=”100%”>
<tr><td></td></tr>
</table>
這對美工人員來說,把圖片拆成HTML方面可能會有困難
但只要把那些定位、大小的屬性全寫在CSS
HTML都用id、class來套CSS樣式的話,AA無障礙標準就會好過一點。
以上如有錯誤,請不吝指教,歡迎提出。
轉載文章是可以,但一定要貼上來源超連結,因為此文章會一直更新,我不想讓有需要的人被誤導
下一篇: