熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

使用Web標准生成ASP.NET 2.0 Web站點一

2022-06-13   來源: .NET編程 

簡介

  Web 標准使您能通過最少的工作生成可被最廣大受眾訪問的 Web 站點Web 標准的承諾是只需設計頁面一次即可讓該頁以完全相同的方式在任何現代的浏覽器中顯示和工作例如在按照標准生成以後旨在在 Microsoft Internet Explorer 中以某種方式顯示的頁可在其他浏覽器(如Mozilla FirefoxNetscape NavigatorOperaCamino 和 Safari)中以相同的方式顯示而無需完成任何額外的工作

  Web 標准的一個額外好處是 — 使 Web 站點更易於為殘疾人士訪問這是一個范圍廣泛的受眾群體包括視力衰退的中年人士剛剛在滑雪時跌斷胳膊的人士以及完全失明的人士等使用標准可避免無意中阻止那些具有暫時性或永久性身體殘疾的人士訪問 Web 頁

  對於生成滿足公共 Web 標准的 Web 站點而言Microsoft ASPNET 框架是最佳的框架特別強調的是ASPNET 框架中的每個控件都按照 XHTML 和可訪問性標准進行了全面的檢查和測試此外Microsoft Visual Studio NET 還包含一些新工具用於按照 XHTML 和可訪問性標准驗證 Web 頁

  本文的目的是為您提供有關 XHTML 和可訪問性標准的概述並說明如何利用 ASPNET 和 Visual Studio NET 來滿足這些標准在本文的結尾將分步演練以下功能即創建能夠同時滿足 XHTML 和可訪問性標准的 ASPNET Web 站點

生成 XHTML Web 站點

  HTML 在正式的場合已經過時了World Wide Web Consortium (WC) 於 日發布了 XHTML 的第一個版本作為推薦標准XHTML 標准的目標是取代 HTML按照 WC 的說法XHTML 是 HTML 的繼承者()

  XHTML 標准的制定者具有兩大目標

&#;

  在文檔結構和表示形式之間創建更明顯的分離

&#;

  將 HTML 重新表示為 XML 的應用程序

  為了實現第一個目標WC 一直在堅定地從 HTML 中刪除純粹描述性的元素和屬性(他們是從 HTML 開始這一過程的)例如XHTML Strict 不包含諸如 <font> 標記之類的元素或諸如 bgcolor 屬性之類的屬性因為這些元素和屬性完全用於描述文檔的外觀它們與文檔的結構沒有任何關系

  WC 一直在努力使 Web 站點設計人員和開發人員摒棄特定標記應當具有特定外觀這一觀念例如您可能會認為 <h> 標記(標題標記)的用途是在頁中呈現大的加粗文本這實際上是錯的<h> 標記用來在文檔中標記標題而不是其他任何東西如何呈現標題標記由浏覽器確定視力衰退的人士使用的屏幕閱讀器可能利用抑揚頓挫的聲音來大聲朗讀標題標記的內容不支持多個字體大小的 PDA 可能用閃爍文本呈現標題標記的內容

  您不應當試圖使用諸如 <h> 標記之類的頁元素來控制 Web 頁的外觀相反您應當通過使用層疊樣式表來指示 Web 頁的外觀而且您所使用的層疊樣式表應當是外部 層疊樣式表請使用標記和屬性來標記文檔的結構而使用樣式表來控制文檔的表示形式

  XHTML 的第二個目標是迫使 HTML 開發人員遵守更為嚴格的 XML 規則按照 WC 的說法XHTML 是 HTML 的作為 XML 應用程序的修訂()換句話說使用 XHTML 生成 Web 頁時實際上是在創建 XML 文檔

  XML 文檔具有比 HTML 文檔更嚴格的語法例如XML 區分大小寫所有 XML 屬性都必須放在引號內而且 XML 標記不能重疊強迫 Web 站點開發人員和設計人員遵守有更高要求的語言規則有很多好處

  好處之一用 XHTML 標記編寫的頁具有更高的跨浏覽器跨設備和跨操作系統兼容性如果在浏覽器中打開傳統的 HTML 頁浏覽器將千方百計地呈現該頁浏覽器將試圖呈現該頁即使您的 HTML 一團糟例如Internet Explorer(以及 Firefox 和 Opera)能夠很好地顯示下面的 HTML 頁

  <i><B>this is bold and italic</I> and this is bold </body></HTML>

  Internet Explorer 會恰當地顯示該頁 — 即使該頁缺少 <html><body> 開始標記<b> 標記不具有匹配的結束標記並且開始和結束 <i> 標記的大小寫不一致所有主要的浏覽器都能適應幾乎任何 HTML 標記混合物並且不顧一切地呈現一些內容

  浏覽器的這種適應行為是危險的因為不同的浏覽器(或相同浏覽器的將來版本或在不同操作系統上運行的相同浏覽器)可能以不同方式呈現錯亂的 HTML實際上對於最新版本的 Internet ExplorerMozilla Firefox 和 Opera 而言它們呈現無效 HTML 的方式驚人地一致但是一旦開始違反游戲規則就不會得到任何保證

  然而如果用 XHTML 的更嚴格的規則編寫 Web 頁那麼 Web 頁就更有可能以一致的方式與當前浏覽器協作並且它們將繼續與當前浏覽器的未來新版本協作對於任何公司而言幾乎都不具備針對每個浏覽器在每個操作系統和每個設備上測試其 Web 站點的資源如果按照 Web 標准編寫頁面那麼就不必具有這樣的資源

XHTML 標准的版本

  有三個版本的 XHTML 它們分別對應三個版本的 HTML

&#;

  XHTML Transitional

&#;

  XHTML Strict

&#;

  XHTML Frameset

  XHTML Transitional 包含 HTML Transitional 中的全部標記和屬性引入 XHTML Transitional 標准的目的是使現有 HTML 設計人員和開發人員無需經歷太多的痛苦就能遷移到 XHTML

  XHTML Strict 與 XHTML Transitional 的不同之處在於它在文檔結構和表示形式之間實施了一種更為明顯的分離與 XHTML Transitional 不同XHTML Strict 強迫您使用層疊樣式表來控制頁的外觀

  XHTML Frameset 文檔意在成為使用 <frameset> 標記將浏覽器劃分為多個框架的文檔(XHTML Transitional 和 Strict 頁不能包含 <frameset> 標記)

  WC 還發布了 XHTML 以作為推薦標准( 日)XHTML 非常類似於 XHTML Strict二者的主要區別在於可以用附加模塊擴展 XHTML 以便支持新元素例如可以生成特定的 XHTML 該頁還包含 MathML(數學標記語言)SVG(可伸縮向量語言)或創建的自定義模塊中的元素

  最後WC 正在制訂 XHTML 推薦標准因為 XHTML 仍然處於起草階段並且當前沒有 Web 浏覽器支持該標准所以我們不在本文討論它

  ASPNET 框架和 Visual Studio NET 面向 XHTML Transitional該標准是 XHTML 標准中限制性最低的而且它是與現有 HTML 頁最兼容的標准但是還可以生成面向 XHTML Strict 標准甚至 XHTML 標准的 ASPNET 頁(請參閱後面的配置 XHTML 一致性一節)

  (請注意默認情況下ASPNET 框架的 Beta 版本面向 XHTML ASPNET 框架的最終版本將面向 XHTML Transitional

創建 XHTML 頁

  與 HTML 頁不同XHTML 頁必須是標准格式且有效的 XML 文檔XHTML 推薦標准的第 部分對 HTML 和 XHTML 之間的區別進行了總結這裡給出生成有效 XHTML 頁的最重要需求的列表

&#;

  頁必須包含有效的 XHTML DOCTYPE

  有效的 XHTML 頁必須在其任何內容之前包含一個 XHTML DOCTYPE當在 Visual Studio NET 或 Microsoft Visual Web Developer 中創建新的 ASPNET 頁時該頁中將自動包含 XHTML Transitional 的正確的 DOCTYPE下面列出四個標准的 XHTML DOCTYPE

  XHTML Transitional

  <!DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd>

  XHTML Strict

  <!DOCTYPE html PUBLIC //WC//DTD XHTML Strict//EN strictdtd>

  XHTML Frameset

  <!DOCTYPE html PUBLIC //WC//DTD XHTML Frameset//EN framesetdtd>

  XHTML

  <!DOCTYPE html PUBLIC //WC//DTD XHTML //EN >

  向頁中添加 DOCTYPE 會影響該頁在浏覽器中的呈現方式請參閱以下標題為XHTML 和 DOCTYPE 切換的一節

&#;

  根元素必須引用 XHTML 命名空間

  XHTML 頁的開始 <html> 標記必須指定默認命名空間 以下是 XHTML Transitional 頁的有效開始 <html> 標記的示例

  <html xmlns= xml:lang=en lang=en>

&#;

  所有元素和屬性名都必須小寫

  XML 區分大小寫因此<p> 標記和 <P> 標記之間存在差異只有前者是有效的 XHTML 段落標記

&#;

  屬性值必須始終放在引號內

  確保始終將屬性值放在雙引號或單引號中例如以下是無效的 XHTML

  <a href=SomePageaspx>Next</a>

  在該示例中href 屬性缺少引號以下代碼是有效的 XHTML

  <a href=SomePageaspx>Next</a>

  您可以通過選擇菜單選項 ToolsOptionsFormat將 Visual Studio NET 和 Visual Web Developer 配置為自動將屬性值放在引號內

&#;

  所有具有開始標記的非空元素都必須具有匹配的結束標記

  如果具有開始 <p> 標記則必須包含結束 </p> 標記來標記段落的結束對於根本不包含任何內容的標記例如 <br> 標記可同時提供開始和結束標記 <br></br>也可以使用空元素簡寫

  為使 XHTML 頁與現有的 HTML 浏覽器向後兼容需要小心處理打開和關閉標記的方式例如現有 HTML 浏覽器傾向於將開始和結束 <br> </br> 標記錯誤地解釋為兩個 <br> 元素因此您應當使用空元素簡寫</br>

  此外除非您小心地在結束斜槓之前添加一個空格否則現有 HTML 浏覽器在處理空元素簡寫時會出現問題因此應當使用 <BR< b>[space] />(而不是)向頁中添加 <br> 元素

&#;

  不得存在重疊標記

  可以使標記嵌套但是不允許使標記重疊例如以下 XHTML 是有效的

  <b><i>This is bold and italic</i></b>

  但是以下 XHTML 是無效的

  <i><b>This is bold and italic</i></b>

&#;

  不得存在屬性最簡化

  所有屬性都必須具有值即使該值看起來有一點兒奇怪例如標記<input type=checkbox checked />是無效的 XHTML因為 checked 屬性不具有值該標記應當寫成<input type=checkbox checked />

&#;

  必須使用 id 屬性而不是 name 屬性

  在 HTML 中可以使用 name 屬性來標識 <a><applet><form><frame><iframe><img><map> 元素盡管可以使用 name 屬性生成 XHTML Transitional 頁但在 XHTML Strict 和 XHTML 標准中已經將 name 屬性刪除您應當改而使用 id 屬性來標識這些元素

&#;

  必須將 <script><style> 元素的內容包裝到 CDATA 節中

  如果在腳本或樣式表中使用特殊字符(例如 < 或 &)或實體引用(例如 <&則需要將腳本或樣式表的內容標記為 CDATA(字符數據)節如下所示

  <script type=text/javascript> <![CDATA[ function isLess(a b) { if (a < b) return true; } ]]> </script>

  使用 CDATA 節並非對所有浏覽器都有效例如Internet Explorer 會將 <script> 標記中的 CDATA 節視為語法錯誤可以通過添加 JavaScript 注釋避免該問題如下所示

  <script type=text/javascript> /* <![CDATA[ */ function isLess(a b) { if (a < b) return true; } /* ]]> */ </script>

  JavaScript 使用 /**/ 來標志注釋的開始和結束因此CDATA 節對 JavaScript 隱藏但不對分析該頁的浏覽器隱藏總之較好的做法是將樣式規則和腳本放在外部文件中而從 XHTML 頁中引用這些文件通過使用外部樣式表和腳本能夠避免上述所有問題


 

XHTML 和 ASPNET 控件

  默認情況下ASPNET 框架中包含的每個 ASPNET 控件都呈現有效的 XHTML換句話說向頁中添加 ASPNET 控件時您無需完成任何特殊工作來生成有效的 XHTML 標記例如如果您向頁中添加 GridView 控件GridView 控件會生成有效的 XHTML 標記

  這裡需要澄清三個要點首先包含 ASPNET 控件的頁的源代碼不會通過 XHTML 驗證驗證 ASPNET 頁時需要驗證頁呈現的內容(在 Internet Explorer 中選擇 View Source 時看到的所有內容)而不是該頁的源代碼

  其次在創建 ASPNET 頁時沒有任何事情阻止您編寫無效的 XHTML您當然可以向 ASPNET 頁中添加希望添加的任何標記例如如果向頁中添加 標記那麼頁將不會通過 XHTML Strict 驗證

  最後當您使用自定義 ASPNET 控件時沒有任何保證如果購買第三方 ASPNET 控件(例如一個一流的增強 DataGrid 控件)則該控件可能會呈現有效的 XHTML但也可能不會保證不犯錯誤是控件供應商的責任

驗證 XHTML 頁

  Visual Studio NET 和 Visual Web Developer 會在生成 Web 頁的過程中自動驗證該頁的有效性通過在違反規則的內容下添加綠色或紅色波浪線Source視圖中指出驗證問題紅色波浪線對應於諸如缺少結束標記之類的驗證錯誤綠色波浪線對應於驗證警告例如使用了已否決的標記

  將鼠標懸停在任何波浪線上方可查看包含驗證錯誤或警告消息的工具提示(參見圖 或者還可以在 Error List 窗口中查看驗證錯誤或警告的列表(依次選擇 ViewOther WindowsError List



   驗證 XHTML 文檔


  默認情況下Visual Studio NET 和 Visual Web Developer 被配置為針對 Internet Explorer 架構驗證頁如果要針對 XHTML 架構驗證頁則需要從工具欄的下拉列表中選擇 XHTML 架構中的一個或依次選擇 ToolsOptionsValidation 來選擇目標架構

  作為替代方法還可以通過使用 WC驗證服務來驗證 ASPNET 頁WC 驗證服務使您能夠通過提供 URL 或通過上載 XHTML 頁的源代碼來驗證頁

XHTML 和 DOCTYPE 切換

  為 Web頁指定 DOCTYPE 會影響浏覽器呈現頁的方式Internet ExplorerMozilla Firefox 和 Opera 全都支持一種名為DOCTYPE 切換(也叫DOCTYPE 嗅探)的功能

  引入 DOCTYPE 切換的目的是使浏覽器能夠正確地呈現符合標准的 Web 站點以及舊式 Web 站點大多數 Web 站點被開發為呈現 HTML 頁而不是 XHTML 頁浏覽器通過判斷是否存在 DOCTYPE 來確定何時應該使用標准來呈現頁

  Internet Explorer + 支持兩種呈現模式分別叫做 Quirks 模式和 Standards 模式當 Internet Explorer 呈現包含有效 XHTML(或 HTML )DOCTYPE 的頁時它會以 Standards 模式呈現該頁否則它會以 Quirks模式呈現該頁(有關詳細信息請參閱 CSS Enhancements in Internet Explorer

  Opera 浏覽器 (Opera +) 支持與 Internet Explorer 相同的兩種呈現模式Quirks 和 Standards(有關詳細信息請參閱 )

  Mozilla Firefox + 支持三種呈現模式Quirks 模式Almost Standards 模式和 Standards 模式Firefox 的 Almost Standards 模式對應於 Internet Explorer 和 Opera 的 Standards 模式當頁包含有效的 XHTML Transitional DOCTYPE(並且該頁被分配為 text/html MIME 類型)時Firefox 會以 Almost Standards 模式呈現該頁當頁包含 XHTML Strict 或 XHTML DOCTYPE(或者該頁被分配為 XML MIME 類型)時該頁將以 Standards 模式呈現(有關詳細信息請參閱 developer/quirks/l)

  可以通過臨時向頁中添加以下客戶端腳本(該腳本在最新版本的 Internet ExplorerFirefox 和 Opera 中有效)確定浏覽器的當前呈現模式

  <script type=text/javascript> alert( patMode ); </script>

  您需要關心浏覽器的呈現模式因為它會影響將層疊樣式表應用於該頁的方式如果將現有 HTML 頁轉換為 XHTML 頁那麼在浏覽器中打開它們時它們可能看起來非常不同

  例如Internet Explorer 以不同方式計算頁元素的大小這取決於呈現模式(它使用不同的 CSS Box Model)在 Quirks 模式下元素的寬度是通過將元素的內容內邊距邊框和邊距相加而計算得到的在 Standards 模式下元素的寬度是只考慮元素內容的寬度而計算得到的

  例如考慮下列兩個 <div> 標記

  <div > First Box </div> <div > Second Box </div>

  除了第二個 <div> 元素的附加內邊距以外這兩個 <div> 元素是相同的在 Quirks 模式(參見圖 )下這兩個 <div> 元素看起來大小相同因為在計算第二個 <div> 元素的寬度時考慮了它的附加內邊距(這兩個元素的總寬度為 px)在 Standards 模式(參見圖 )下第二個 <div> 元素看起來要比第一個 <div> 元素寬因為在計算元素的寬度時未考慮內邊距(這兩個元素的總寬度大於 px)



   Quirks 模式




   Standards 模式


  這只是 Quirks 模式下浏覽器差異的一個示例在 Quirks 模式下每個浏覽器都以相當不同的方式實現 WC層疊樣式表標准有關切換到 Standards 模式的一個妙處在於它強制幾乎所有現代浏覽器以非常類似的方式(不完全相同但要好得多)解釋 WC標准

  如果希望 Web 頁以相同方式出現在所有浏覽器中那麼通過包含 XHTML Transitional DOCTYPE 觸發 Standards 模式(在 Internet Explorer 和 Opera 中)和 Almost Standards 模式(在 Firefox 中)是一個好主意幸運的是默認情況下Visual Studio NET 和 Visual Web Developer 自動將該 DOCTYPE 添加到每個新的 ASPNET 頁中

XHTML 和 MIME 類型

  當 Web 浏覽器從 Web 服務器請求頁時Web 服務器會為該頁分配特定的 MIME 類型(也稱為 Content 類型)例如HTML 頁被分配為 text/html MIME 類型GIF 圖像被分配為 image/gif MIME 類型而 Microsoft Word 文檔被分配為 application/msword MIME 類型

  浏覽器使用 MIME 類型來確定如何處理頁(或其他資源)例如如果浏覽器從 Web 服務器獲得一個具有可識別圖像 MIME 類型的文件則浏覽器嘗試將該文件解釋並呈現為圖像如果浏覽器獲得一個具有 application/msword MIME 類型的文件則該浏覽器可能自動打開 Microsoft Word 以顯示該文檔(這裡的確切行為取決於浏覽器及其配置方式)

  WC 為 XHTML 文檔引入了一個 MIME 類型這一新的 MIME 類型是 application/xhtml+xmlWC 建議您在提供 XHTML 文檔時使用 application/xhtml+xml MIME 類型因為 XHTML 頁應該以比舊式 HTML 頁更嚴格的方式進行解釋

  通過在頁指令中包含 ContentType 屬性為 ASPNET 頁分配特定的 MIME 類型例如在 ASPNET 頁的頂部包含以下指令會導致為該頁分配 application/xhtml+xml 類型

  <%@ ContentType=application/xhtml+xml %>

  WC 的推薦標准有一個突出問題並非所有浏覽器都能識別 application/xhtml+xml特別需要指出的是Internet Explorer(有史以來最為流行的 Web 浏覽器)不能識別 application/xhtml+xml MIME 類型因此使用推薦的 application/xhtml+xml MIME 類型提供 XHTML 頁不是一個可行的選擇

  有三種解決該問題的方式可以使用 text/html MIME 類型來提供 XHTML 頁或者使用 application/xml(或 text/xml)MIME 類型來提供 XHTML 頁也可以使用內容協商方式讓我們對上述每個選擇進行探討

  第一個選擇 — 以 text/html 類型提供頁 — 是最容易的選擇默認情況下ASPNET 頁被分配為該 MIME 類型更好的做法是按照 WC 的建議在向現有的 HTML 浏覽器提供頁時使用這一選擇(請參閱 mediatypes/)如果創建的是 XHTML Transitional 頁並且 Web 應用程序的主要受眾使用不能理解 application/xhtml+xml MIME 類型的浏覽器那麼以 text/html 類型提供頁似乎十分明智畢竟引入 XHTML Transitional 標准的目的是使開發人員能夠更為容易地將現有的 HTML 頁遷移到 XHTML

  這一主張是有爭議的例如Ian Hickson 認為絕不應該以 text/html 類型提供 XHTML 頁因為這樣會導致隨便的不標准的 XHTML 頁(請參閱 )他建議作者們繼續堅持使用 HTML 直到更多的浏覽器完全支持 XHTML 標准為止

  第二個選擇是使用 application/xml 或 text/xml MIME 類型以 XML 類型提供 XHTML 頁在向 Internet Explorer 提供 XML 文檔時該文檔會作為 XML 文檔進行分析並呈現到浏覽器中(該文檔由 documentXMLDocument 對象公開的 XML DOM 表示

  以 XML 類型提供 XHTML 文檔的優點是XHTML 文檔具有的任何問題都會被 Internet Explorer 的 XML 分析器捕獲例如如果文檔包含重疊標記或者如果沒有將屬性的值包裝到引號內則不會呈現該文檔並且會顯示錯誤信息(參見圖 XHTML 純粹主義者認為該行為是一件好事因為它可以防止您編寫格式錯誤的 XHTML



   在 Internet Explorer 中顯示 XML


  該方法的問題是默認情況下Internet Explorer 呈現 XML 文檔的源代碼因此如果以 XML 類型提供 XHTML 文檔則 Web 站點訪問者將看到 XHTML 文檔的源代碼而不是預期的呈現輸出WC 推薦了一個用來解決該問題的竅門(請參閱 faq#ie)如果通過使用 XSLT 轉換將 XHTML 文檔轉換為 HTML那麼文檔將分析為 XML 並顯示為 HTML

  例如清單 中的 ASPNET 頁將以 XML 文檔的形式提供但被轉換為 HTML 文檔結果頁會正確地顯示在 Internet ExplorerOpera 和 Firefox 中

  清單 XMLPageaspx

  <%@ Page Language=VB ContentType=text/xml %> <?xmlstylesheet type=text/xsl ?> <!DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd> <html xmlns= > <head runat=server> <title>My Page</title> </head> <body> <form id=form runat=server> <div> <asp:TextBox ID=txtFirstName runat=server /> </div> </form> </body> </html>

  頁指令會導致該頁以 text/xml 類型呈現清單中的第二行引用了一個名為 copyxsl 的 XSLT 樣式表它會對當前文檔執行標識轉換換句話說除了將原始XML 文檔中的所有元素復制到新的 HTML 文檔中以外它根本沒有做任何事情copyxsl 的源代碼包含在清單

  清單 Copyxsl

  <stylesheet version= xmlns=> <template match=/> <copyof select=/> </template> </stylesheet>

  該解決方案是有效的但它似乎不是很精彩當分析 XML 文檔時的確獲得了額外的驗證步驟但是如果在 Visual Studio NET 或 Visual Web Developer 中生成 ASPNET 頁那麼開發環境會在Source視圖中執行相同的驗證最後Internet Explorer 將收到與向它發送 text/html 類型文檔時相同的文檔

  第三個選擇 — 內容協商將 WC 推薦標准的精神與最大程度的浏覽器兼容性最佳地組合在一起(請參閱 mimetype/contentnegotiation)當使用內容協商時會以不同的 MIME 類型向不同的浏覽器提供 ASPNET 頁如果浏覽器聲稱它支持 XHTML則向它提供 XHTML 類型的頁否則以 text/html MIME 類型向該浏覽器提供頁

  清單 中的 Globalasax 包含向不同的浏覽器提供不同 MIME 類型頁所需的代碼如果將該文件添加到 Web 項目中則每個 ASPNET 頁的 MIME 類型都會隨著每個請求而修改將頁提供給 Firefox 或 Opera 時該頁以 application/xhtml+xml 類型提供另一方面Internet Explorer 會收到 text/html 頁

  清單 Globalasax

  <script runat=server> Sub Application_PreSendRequestHeaders(ByVal s As Object _ ByVal e As EventArgs) If ArrayIndexOf(RequestAcceptTypes _ application/xhtml+xml) > Then ResponseContentType = application/xhtml+xml End If End Sub </script>

配置 XHTML 一致性

  ASPNET 框架的默認行為是呈現針對 XHTML Transitional 能夠通過驗證的頁生成 Web 站點的大多數開發人員都希望面向該標准因為它是與現有 HTML 頁最為兼容的標准但是在某些情況下該標准可能顯得太松散或太嚴格

  例如如果您志向遠大那您也許要生成 XHTML Strict(甚至 XHTML )的 Web 站點畢竟XHTML Transitional 標准的目標是充當通往這些更具限制性標准的跳板默認情況下因為 ASPNET 框架面向 XHTML Transitional所以某些 ASPNET 控件會呈現與 XHTML Strict 或 XHTML 不兼容的屬性

  而且有時您還可能發現 XHTML Transitional 標准的限制性過高Microsoft 必須對現有 ASPNET 控件進行多項更改才能符合 XHTML Transitional 標准其中一些更改可能會破壞現有的 ASPNET Web 站點

  為了滿足每個人的要求Microsoft 創建了一個名為 xhtmlConformance 的新配置選項您可以在 Web 站點的配置文件中設置該選項新的配置選項使您能夠指定 Web 頁的 XHTML 一致性的級別它的內容如下所示

  <configuration> <systemweb> <xhtmlConformance mode=transitional /> </systemweb> </configuration>

  默認情況下xhtmlConformance 設置為值 transitional但是還可以將該選項設置為值 strictlegacy

  如果將 xhtmlConformance 選項設置為 strict那麼標准的 ASPNET 控件將不會再呈現某些屬性例如ASPNET <form> 控件將不再呈現 name 屬性除非 ASPNET 頁包含(不符合標准的)客戶端腳本否則從 transitional 模式切換到 strict 模式時不會注意到任何變化

  如果將 xhtmlConformance 選項設置為 legacy那麼對於某些元素和屬性(但不是全部)ASPNET 框架將恢復為 ASPNET 呈現行為在這種情況下ASPNET 框架將呈現不與任何 XHTML 標准兼容的內容並且頁將不再通過 XHTML 標准驗證例如在 legacy 模式下呈現 <br> 標記時不會呈現它需要的 XHTML 結束斜槓 (<br />)只有在將現有 ASPNET 應用程序遷移到 ASPNET 的過程中遇到問題時xhtmlConformance 設置為 legacy 模式才是有意義的

生成可訪問的 ASPNET Web 站點

  遵守公共 Web 標准的好處是它們使您以盡可能少地工作使盡可能多的人能訪問您的 Web 頁需要指出的是可訪問性標准使您能夠生成可被殘疾人士更容易訪問的 Web 站點

  同樣要強調的是Web 站點用戶中的相當一部分具有這樣或那樣的殘疾請試想一下您自己的家庭成員並且考慮他們中有多少人會在與 Web 頁交互時遇到麻煩我就有一些上了年紀的親戚是盲人或者失去了動作協調性我猜測本文的很多讀者也有上了年紀的父母或祖父母他們在使用大多數 Web 站點時會遇到很多困難

  生成可訪問的 Web 站點有很多充分的理由財務道德法律等等但是我們將重點討論法律動機在美國按照康復法案 (Rehabilitation Act) 節的要求聯邦政府機構開發的任何 Web 站點都要使殘疾人士可以訪問這一法律適用於聯邦政府機構以及與聯邦政府機構訂立合同的公司(請參閱 )

  其他國家/地區也具有類似的要求例如在加拿大Treasury Board Common Look and Feel Standards 要求聯邦政府機構開發的 Web 站點都要使殘疾人士可以訪問在澳大利亞Disability Discrimination Act 要求澳大利亞服務器上承載的所有 Web 站點(無論其是否是政府的 Web 站點)都要使殘疾人士可以訪問(有關可訪問性法律的詳細信息請參閱

  在我知道的 Web 站點開發人員中沒有任何人會故意生成殘疾人士無法訪問的 Web 站點問題在於大多數開發人員都不熟悉各種可訪問性標准

  在本文的下列各節中將概述以下兩個最重要的可訪問性標准WCAG 和 節標准您還將學習如何通過使用 ASPNET 控件生成可訪問的 Web 頁最後您將學習如何驗證Web 頁的可訪問性

可訪問性標准

  幾乎所有可訪問性標准和法律都源自 WC Web Content Accessibility Guidelines (WCAG)這些准則是由 World Wide Web Consortium 在 日作為推薦標准首次發布的(請參閱 )

  WCAG 包含 條准則每一條准則又包含一個或多個進一步闡明該准則的檢查點每個檢查點都按 的優先級進行分級為使這些准則的實施變得更加容易WC 已經發布了一組文檔其中包含有關如何遵守這些准則的技術(請參閱 TECHS/)

  您可以要求不同程度地遵守 WCAG 准則如果要求 Web 站點滿足所有優先級 的檢查點則您可以顯示具有 Conformance Level A 的標識語當 Web 站點滿足所有優先級 檢查點時該 Web 站點可以顯示 Conformance Level DoubleA 標識語最後滿足所有檢查點的 Web 站點可以顯示 Conformance Level TripleA 標識語(請參閱 )

   節准則源自 WCAG 准則在美國聯邦政府機構(以及與聯邦政府機構訂立合同的公司)需要對這組准則給予最高程度的關注因為這些准則具有法律效力您可以在 節 Web 站點讀到 節准則的完整文本

  ASPNET 框架旨在使您能夠滿足所有 WCAG 優先級 和優先級 的檢查點以及所有 節准則這些准則使用起來非常嚴格每個使用 ASPNET 框架的開發人員都需要檢查和測試每個 ASPNET 控件的可訪問性而且每個開發人員都應該在桌面上安裝一個屏幕閱讀器以便針對這些准則測試頁

ASPNET 中的可訪問性改進

  本文重點討論 ASPNET 框架中六個方面的可訪問性改進在下列各節中您將學習如何使用 ASPNET 控件來顯示可訪問的圖像表單導航數據和 XHTML在本節結尾我們還將考慮與在 ASPNET 頁中使用客戶端腳本有關的可訪問性問題

創建可訪問的圖像

  您不應當做這樣的假設與 Web 站點交互的每個人都可以實際看到您的 Web 站點如果某個人是盲人或者視力不足那麼這個人就可能需要使用屏幕閱讀器或盲文顯示器來訪問您的 Web 頁屏幕閱讀器通過使用語音合成器來朗讀 Web 頁中的文本盲文顯示器將頁中的文本轉換為盲文表示

  對於無法看到它們的人而言圖像和其他非文本頁元素(例如JavaShockwave 和 Flash 內容)都是沒有用的如果您希望使 Web 站點對於盲人或弱視的人是可訪問的那麼需要為 Web 頁中的所有非文本內容提供文本等效內容

  Web 頁中的每個圖像都應該包含 alt 屬性alt 屬性用來表示由屏幕閱讀器或其他輔助性設備閱讀的替換文本以下是 alt 屬性的使用方式

  <img src=Productsgif alt=Image of Products />

  alt 屬性應當包含圖像的說明在任何情況下它都不應該只是包含該圖像的文件名alt 屬性的目的是為盲人和視力正常的人傳遞相同的圖像信息寫入 alt 屬性的值時要求對該元素的含義進行人工解釋因此不能自動完成創建 alt 屬性的過程

  每個顯示圖像的 ASPNET 控件都包含用於為該圖像提供替換文本的方法例如ASPNET 圖像控件包含 AlternateText 屬性如果使用 Image 控件則需要將 AlternateText 屬性設置為有意義的值

  <asp:Image ImageUrl=Productsgif AlternateText=Image of Products Runat=Server />

  如果某個圖像只是用作設計元素則應當將它的 alt 屬性設置為空字符串如果圖像不具有需要傳達的有用信息那麼就沒有理由使屏幕閱讀器的頁解說變得散亂

  <img src=PageDividergif alt= />

  在 ASPNET 框架中必須采取特殊措施使您能夠呈現空的 AlternateText如果將空文本分配給 ASPNET 控件的屬性則 ASPNET 控件將根本不會呈現該屬性例如假設將以下 ASPNET Image 控件添加到頁中

  <asp:Image ImageUrl=PageDividergif AlternateText= Runat=Server />

  在這種情況下會呈現以下標記

  <img src=PageDividergif />

  請注意alt 屬性消失了這是所有 ASPNET 控件屬性的默認行為當沒有為屬性分配值時該屬性不會呈現出來遺憾的是在這種情況下我們確實希望為 alt 屬性呈現空值

  為了解決該問題ASPNET 框架中引入了以下新屬性使您能夠用 Image 控件顯示空替換文本GenerateEmptyAlternateText 屬性

  <asp:Image ImageUrl=PageDividergif GenerateEmptyAlternateText=true Runat=Server />

  如果使用 GenerateEmptyAlternateText 屬性則會正確地呈現 alt= 屬性

  當圖像表示某個真正復雜的事物(例如組織結構圖)時不能使用 alt 屬性來提供替換文本說明當需要提供較長的圖像含義說明時需要使用 longdesc 屬性

  longdesc 屬性接受相對或絕對 URL 作為它的值該 URL 應當鏈接到包含圖像內容的文本說明的頁以下示例說明如何將該屬性與 <img> 標記配合使用

  <img src=OrgChartgif alt=Company Organization Chart longdesc=/OrgChartDescriptionaspx />

  ASPNET Image 控件包含一個名為 DescriptionUrl 的屬性它對應於 HTML longdesc 屬性以下示例說明如何使用該屬性

  <asp:Image ImageUrl=OrgChartgif AlternateText=Company Organization Chart DescriptionUrl=/OrgChartDescriptionaspx Runat=server />


 

創建可訪問的表單

  Web 頁表單可能給視力低下的人士以及缺乏動作協調性的人士帶來問題如果通過屏幕閱讀器訪問 Web 頁表單那麼可能很難將表單域與其相應的標簽相關聯例如假設 Web 頁包含以下表單

  <table> <tr> <td>First Name:</td> <td><input name=txtFirstName /></td> </tr> <tr> <td>Last Name:</td> <td><input name=txtLastName /></td> </tr> </table>

  該表單顯示一個人的名和姓的輸入域在這種情況下因為該表單顯示在表中所以屏幕閱讀器用戶可能很難將正確的標簽與正確的表單域相關聯HTML 中引入以下新標記以使您能夠將表單域標簽與表單域相關聯<label> 標記下面說明如何使用 <label> 標記編寫前面的表單

  <table> <tr> <td><label for=txtFirstName>First Name:</label></td> <td><input name=txtFirstName id=txtFirstName /></td> </tr> <tr> <td><label for=txtLastName>Last Name:</label></td> <td><input name=txtLastName id=txtLastName /></td> </tr> </table>

  <label> 標記將表單域標簽與其相應的表單域顯式關聯起來請注意<input> 域包含 id 屬性這是因為 for 屬性的值必須是輸入域的 id 屬性而不是 name 屬性

  通常ASPNET Label 控件生成 <span> 標記但是如果您在聲明 ASPNET Label 控件時提供了 AssociatedControlId 屬性則該控件會呈現 <label> 標記下面說明如何用 ASPNET LabelTextBox 控件生成可訪問的表單

  <table> <tr> <td><asp:Label AssociatedControlID=txtFirstName runat=server>First Name:</asp:Label></td> <td><asp:TextBox ID=txtFirstName runat=server /></td> </tr> <tr> <td><asp:Label AssociatedControlID=txtLastName runat=server>Last Name:</asp:Label></td> <td><asp:TextBox ID=txtLastName runat=server /></td> </tr> </table>

  在為 ASPNET 控件提供標簽時應當使用 ASPNET Label 控件而不是 HTML <label> 標記在將一個 ID 分配給 ASPNET 控件(如 TextBox 控件)時呈現到浏覽器中的 ID 可能與您分配給該控件的 ID 不同因此如果使用 <label> 標記<label> 標記中的 ID 可能與所呈現的 TextBox 控件的 ID 不匹配另一方面如果使用 ASPNET Label 控件則不必擔心該問題

  ASPNET CheckBoxRadioButtonCheckBoxListRadioButtonList 控件自動呈現 <label> 標記在使用這些控件時請小心使用 Text 屬性來標記控件的文本您不應該執行以下操作

  <asp:CheckBox Runat=Server /> Include Gift Wrap

  相反請執行以下操作

  <asp:CheckBox Text=Include Gift Wrap Runat=Server />

  對於通過屏幕閱讀器與 Web 頁進行交互的用戶大型表單也可能產生問題在聆聽大型表單的內容時很容易忘記正在聆聽該表單的哪個部分在顯示大型表單時將該表單劃分為多個小塊是一個好主意您可以通過使用 <fieldset> 標記將單個表單劃分為多個部分以下示例說明如何使用該標記

  <form id=form runat=server> <div> <fieldset> <legend>Contact Information</legend> form fields </fieldset> <fieldset> <legend>Payment Information</legend> form fields </fieldset> </div> </form>

  該表單通過 <fieldset> 標記劃分為兩個子表單<legend> 標記用來標記這些子表單的用途在 Internet ExplorerFirefox 和 Opera 中顯示時這些子表單被邊框直觀地劃分為多個單獨的區域(參見圖 但是重要的是要記住<fieldset> 標記的主要用途是實現可訪問性如果不喜歡 <fieldset> 標記的可視化外觀那麼可通過樣式表規則修改該標記的外觀或通過使用 CSS displayvisibility 屬性將該標記完全隱藏



  


  視力低下的人士並不是 Web 頁用戶中唯一可能覺得 Web 表單難以訪問的人那些缺乏動作協調性的用戶也會在與表單交互時遇到困難

  在生成 Web 表單時為每個表單域包含 accesskeytabindex 屬性總是一個好主意accesskey 屬性使無法使用鼠標的用戶能夠直接導航到任何表單域tabindex 屬性使您能夠控制表單域的 Tab 鍵順序對於那些必須通過鍵盤(或像鍵盤一樣操作的輔助性設備)與頁面進行交互的用戶而言這兩個屬性可使其生活變得更方便一些

  下面是一個同時使用 accesskeytabindex 屬性的示例表單

  <asp:Label AssociatedControlID=txtFirstName AccessKey=f runat=server><u>F</u>irst Name</asp:Label> <asp:TextBox id=txtFirstName TabIndex= Runat=server /> <br /> <asp:Label AssociatedControlID=txtLastName AccessKey=l runat=server><u>L</u>ast Name</asp:Label> <asp:TextBox id=txtLastName TabIndex= Runat=server />

  tabindex 屬性用來控制表單域的 Tab 鍵順序因為第一個表單域具有的 tabindex 值為 所以當用戶第一次按 Tab 鍵時該頁中任何出現在該表單之前的其他元素都被跳過

  在使用 Internet Explorer 或 Firefox 時按 ALT+F 可自動將焦點移至 First Name 文本框如果按 ALT+L則焦點會自動移至 Last Name 文本框在使用 Opera 時必須首先按 SHIFT+ESC然後才能選擇訪問鍵

  請注意First NameLast Name 標簽的第一個字母都帶有下劃線通過為字母添加下劃線可以為 Web 站點的用戶提供訪問鍵的直觀表示這是在 Microsoft Windows 應用程序中標記訪問鍵的標准方式但是還有其他在表單中指示訪問鍵的推薦方法(請參閱 ~jkorpela/forms/l)

  使用下劃線指示訪問鍵的一個問題是無法為按鈕中的字符添加下劃線並且超鏈接已經帶有下劃線例如下面的 Button 控件並不像您預期和希望的那樣工作

  <asp:Button Text=<u>S</u>ubmit Runat=server />

  在呈現該 ASPNET Button 控件時會顯示實際文本 Submit而不是顯示帶下劃線的<u>S</u>字符ASPNET Button 控件呈現 HTML<input type=submit> 標記但遺憾的是 <input type=submit>標記不支持下劃線

  您可能認為可以通過使用樣式規則解決該問題遺憾的是當前不存在以下這種跨浏覽器兼容方法使用層疊樣式表為 <input type=submit>標記中的單個字符加下劃線

  如果您願意在頁中使用客戶端 JavaScript則可以解決該問題清單 中的頁包含的 JavaScript 根據是否按下 ALT 鍵而顯示或隱藏所有訪問鍵當按下 ALT 鍵時會彈出一個框顯示訪問鍵鍵盤組合鍵(參見圖 該腳本在 Internet Explorer 和 Firefox 中都能夠正常工作(Opera 不使用 ALT 鍵來選擇訪問鍵)



   AccessKeysaspx


  清單 AccessKeysaspx

  <%@ Page Language=VB %> <!DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd> <html xmlns= > <head id=Head runat=server> <title>Contact Form</title> <style type=text/css> accessKey { display:none; position:absolute; zindex:; padding:px; border:solid px black; backgroundcolor: #ffffe } </style> <script type=text/javascript> /* <![CDATA[ */ windowonload = function() { documentonkeydown = displayAccessKeys; } function displayAccessKeys(e) { if (!e) e = windowevent; if (ekeyCode == ) { toggleAccessKeys(); documentonkeydown = null; documentonkeyup = hideAccessKeys; } } function hideAccessKeys(e) { if (!e) e = windowevent; if (ekeyCode == ) { toggleAccessKeys(); documentonkeyup = null; documentonkeydown = displayAccessKeys; } } function toggleAccessKeys() { var spans = documentgetElementsByTagName(span); for (var k=;k<spanslength;k++) if (spans[k]className == accessKey ) { if ( inline != spans[k]styledisplay) spans[k]styledisplay = inline; else spans[k]styledisplay = none; } } /* ]]> */ </script> </head> <body> <form id=form runat=server> <div> <table> <tr> <td> <asp:Label ID=lblFirstName AssociatedControlID=txtFirstName AccessKey=f runat=server>First Name</asp:Label> </td> <td> <asp:TextBox ID=txtFirstName runat=server /> <span class=accessKey>access key is f</span> </td> </tr> <tr> <td> <asp:Label ID=lblLastName AssociatedControlID=txtLastName AccessKey=l runat=server>Last Name:</asp:Label> </td> <td> <asp:TextBox ID=txtLastName runat=server /> <span class=accessKey>access key is l</span> </td> </tr> <tr> <td colspan=> <asp:Button Text=Submit runat=server /> <span class=accessKey>access key is s</span> </td> </tr> </table> </div> </form> </body> </html>

  清單 中的頁包含樣式表和客戶端 JavaScript樣式表隱藏了由 accessKey 類標識的任何 <span> 標記的內容JavaScript 會在 ALT 鍵已經被按下時進行檢測並且顯示 <span> 標記的內容

  請注意即使 Web 浏覽器中禁用了樣式表和 JavaScript該頁也能夠正常工作在這種情況下將總是顯示訪問鍵幫助(參見圖



   AccessKeysaspx 適度降格



 

創建可訪問的導航

  我討厭撥打客戶支持電話並按照自動系統的指示操作當計算機語音系統用其低沉單調的聲音宣布每個選項時我感覺自己正在慢慢地變老如果按錯了一個鍵那麼您就會永遠迷失在自動計算機系統深不可測的迷宮中

  遺憾的是如果您被迫使用屏幕閱讀器那麼這正是您在訪問幾乎任何 Web 頁時的體驗大多數 Web 站點都在每一頁中包含一個導航欄其中包含指向 Web 站點各個部分的鏈接列表如果使用屏幕閱讀器則每當您打開頁時都必須逐個聆聽這些導航鏈接中的各個鏈接

  通過對導航欄進行一處簡單的修改就可顯著提高 Web 頁的可訪問性只需添加一個用來跳過所有導航鏈接的方法可以用跳過導航鏈接完成該工作

  例如CNN Web 站點包含一個導航欄其中列出了 CNN Web 站點的不同部分(WorldUSWeather 等等)但是CNN Web 站點的設計人員已經做了一件聰明的事情如果查看頁的源代碼則您將注意到導航欄上會出現以下鏈接

  <a HREF=#ContentArea TARGET=_self> <img src= alt=Click here to skip to main content width= height= border= align=right></a>

  當查看 CNN Web 站點的主頁時您絕對不會看到該鏈接該鏈接中包含的圖像是一幅透明的單像素圖像但是如果您用屏幕閱讀器訪問該頁則會閱讀與該圖像相關聯的替換文本盲人可以選擇跳過所有導航鏈接並直接移至 Web 頁的主要內容區域(這與在自動語音系統中按 並直接導航到話務員等效)

  跳過導航鏈接已經被集成到多個標准 ASPNET 控件中特別需要指出的是MenuTreeViewSiteMapPathWizardCreateUserWizard 控件全都支持跳過導航鏈接

  例如清單 中的頁包含 ASPNET Menu 控件該控件用來顯示指向該 Web 站點中其他頁的鏈接列表

  清單 SiteMenuaspx

  <%@ Page Language=VB %> <!DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd> <html xmlns= > <head runat=server> <title>Skip Navigation</title> </head> <body> <form id=form runat=server> <div> <asp:Menu id=Menu Runat=server> <Items> <asp:MenuItem Text=Home NavigateUrl=Homeaspx /> <asp:MenuItem Text=Products NavigateUrl=Productsaspx /> <asp:MenuItem Text=Services NavigateUrl=Servicesaspx /> <asp:MenuItem Text=About NavigateUrl=Aboutaspx /> </Items> </asp:Menu> <hr /> Here is the main content of the page </div> </form> </body> </html>

  如果查看清單 中頁的源代碼您將看到以下鏈接出現在菜單頂部

  <a HREF=#Menu_SkipLink TARGET=_self><img alt=Skip Navigation Links src=/WebResourceaxd?d=ChXzGuDxNmTcWyCl_w&amp;t= width= height= />

  該鏈接包含一幅在您查看該頁時不會出現的寬和高皆為零的圖像但是通過屏幕閱讀器訪問該頁的用戶可以選擇跳過導航鏈接跳到該菜單的結尾

  默認情況下跳過導航鏈接包含文本 Skip Navigation Links可以通過更改 Menu 控件的 SkipLinkText 屬性修改該值

創建可訪問的數據

  ASPNET 框架包含一組豐富的用於顯示數據庫數據的控件這些控件包括 GridViewDetailsViewDataListFormViewRepeater 控件默認情況下GridViewDetailsViewDataList 控件在 HTML 表中顯示數據庫記錄

  在 HTML 表中呈現信息時如果操作錯誤則可能引起可訪問性問題在聆聽 HTML 表的內容時您很容易忘記自己當前在該表中的位置例如假設您使用 HTML 表顯示一個產品信息列表在聆聽由屏幕閱讀器朗讀的表內容時您很容易將某個表單元格所代表的信息搞混不知道它們是有關產品名稱的還是有關所訂購產品數量的抑或是有關存儲這些產品的倉庫的代碼

  在查看 HTML 表時可通過掃視列或行標題來確定特定單元格的含義為使表對於使用屏幕閱讀器的用戶是可訪問的需要顯式標記表標題並將這些標題與各個單元格顯式關聯起來

  在創建表以顯示數據時應當始終使用正確的標記來標記列和行標題表標題應當總是用 <th> 標記進行標記如下所示

  <table> <thead> <tr> <th>Product Name</th> <th>Price</th> </tr> </thead> <tbody> <tr> <td>Milk</td> <td>$</td> </tr> <tr> <td>Cereal</td> <td>$</td> </tr> </tbody> </table>

  在該示例中<th> 標記用來標記以下兩個列標題Product NamePrice

  一些設計人員避免使用 <th> 標記因為他們不喜歡它的默認可視化外觀在大多數浏覽器中<th> 標記的內容居中並且加粗但是需要記住的是標記絕不應當用來控制表示形式如果您希望列標題看起來像標准的表單元格則您應當添加如下所示的樣式規則

  <style type=text/css> th {textalign:left;fontweight:normal} </style>

  為了使表可訪問還應當顯式指明與各個單元格相關聯的一個或多個標題您可以將多個屬性用於此目的scopeheadersaxis

  scope 屬性可用來指示表標題是列標題還是行標題例如下面的表同時包含列標題和行標題它們都通過使用 scope 屬性的 <th> 標記進行標記

  <table> <thead> <tr> <th></th> <th scope=col>First Train</th> <th scope=col>Last Train</th> </tr> </thead> <tbody> <tr> <th scope=row>Alewife</th> <td>:am</td> <td>:am</td> </tr> <tr> <th scope=row>Braintree</th> <td>:am</td> <td>:am</td> </tr> </tbody> </table>

  該表包含 Boston 地鐵 Red Line 的時間表(參見圖 請注意每個列標題都包含 scope=col 屬性而每個行標題都包含 scope=row 屬性



   簡單的地鐵時間表


  scope 屬性非常適合於簡單的表但是對於更為復雜的表需要使用 headers 屬性例如嵌套表可能有三個或更多的標題與單個單元格相關聯headers 屬性使您能夠用與各個單元格相關聯的標題來標記它

  axis 屬性使您能夠對表標題進行分類例如在地鐵時間表中可以將屬性 axis=location 添加到每個表示位置的標題(AlewifeBraintree 標題)中axis 屬性接受由逗號分隔的類別列表


From:http://tw.wingwit.com/Article/program/net/201311/13772.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.