先決條件
在本文中,您將使用最新的 Web 技術(shù)開(kāi)發(fā) Web 應(yīng)用程序。這里的大部分代碼只是 HTML、JavaScript 和 CSS — 所有 Web 發(fā)人員的核心技術(shù)。所需的最重要的工具是用于進(jìn)行測(cè)試的瀏覽器。本文大部分代碼將在最新桌面瀏覽器上運(yùn)行,但也有一些例外,我們將在文章中進(jìn)行說(shuō)明。當(dāng)然,您也必須在移動(dòng)瀏覽器上測(cè)試,為此,您需要最新的 iPhone 和 Android SDKs。本文將使用 iPhone SDK 3.1.3 和 Android SDK 2.1。參見(jiàn) 參考資料 獲取鏈接。
通過(guò) Canvas 實(shí)現(xiàn)圖形效果
多年以來(lái),Web 開(kāi)發(fā)人員一直在抱怨 Canvas。現(xiàn)在,為何還有人會(huì)抱怨瀏覽器中的一個(gè)原生畫(huà)圖 API 呢?畢竟,它允許您創(chuàng)建某種圖形界面,否則您將需要某種瀏覽器插件(每位移動(dòng) Web 開(kāi)發(fā)人員都知道,插件在一些最流行的移動(dòng)瀏覽器上并不可用)。Web 開(kāi)發(fā)人員抱怨 Canvas 的原因是:盡管現(xiàn)在它可用于 Firefox 和 Safari 已經(jīng)很多年,但最流行的桌面瀏覽器 Microsoft®Internet Explorer® 一直不支持它。甚至 Internet Explorer 9 的早期版本也不支持 Canvas。因此,多年來(lái),Canvas 一直是最大的技術(shù)笑話。您可能會(huì)發(fā)現(xiàn),這些令人驚嘆的 Canvas 樣例遍布整個(gè) Internet,但您不能僅僅因?yàn)?Internet Explorer 不支持它就將它用于大多數(shù) Web 應(yīng)用程序。幸運(yùn)的是,對(duì)于移動(dòng) Web 開(kāi)發(fā)人員來(lái)說(shuō),Canvas 沒(méi)有這樣的限制。您瞄準(zhǔn)的所有基于 Webkit 的瀏覽器都能實(shí)現(xiàn) Canvas 并極大地優(yōu)化其性能。
Canvas API 是一個(gè)低級(jí)畫(huà)圖 API,它支持創(chuàng)建直線、曲線、多邊形和圓圈,并用彩色、漸變色等填充它們。在 Canvas 上,您可以創(chuàng)建文本,執(zhí)行各種各樣的幾何轉(zhuǎn)換。可以想見(jiàn),這樣的 API 的用途是無(wú)限的。我們來(lái)看一個(gè)使用 Canvas 來(lái)創(chuàng)建一個(gè)圖形報(bào)告的應(yīng)用程序。圖 1 展示了該應(yīng)用程序的屏幕截圖:一個(gè)顯示每年結(jié)果的柱狀圖。
圖 1. 運(yùn)行在 Android 瀏覽器上的基于 Canvas 的報(bào)告應(yīng)用程序
圖 1 所顯示的并不是瀏覽器中的一幅靜態(tài)圖像。這個(gè)報(bào)告圖形是使用這個(gè) Canvas API 實(shí)時(shí)生成的。清單 1 展示了創(chuàng)建這個(gè)報(bào)告的 HTML。
清單 1. 報(bào)告 HTML
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <meta name="viewport" content="width=device-width; initial-scale=1.0;
- maximum-scale=1.0; user-scalable=0;"/>
- <meta name="apple-touch-fullscreen" content="YES" />
- <title>HTML 5 Reports</title>
- <script type="text/javascript">
- function init(){
- var data = [{year : "2007",sales : 49},
- {year : "2008",sales : 131},
- {year : "2009",sales : 294},
- {year : "2010",sales : 405}];
- var report = {x : "year",
- y : "sales",
- values : data};
- graph(report, 350, 300);
- }
- </script>
- </head>
- <body onload="init()">
- <canvas id="graph"></canvas>
- </body>
- </html>
這個(gè)清單展示了基本的 HTML 結(jié)構(gòu)。這個(gè)文檔的主體擁有一個(gè)單一的 canvas 標(biāo)記。在 init 函數(shù)(在文檔主體加載時(shí)調(diào)用)中,您定義靜態(tài)數(shù)據(jù)(報(bào)告數(shù)據(jù))并將其傳遞到 graph 函數(shù)。盡管這里將報(bào)告定義為靜態(tài)數(shù)據(jù),但很容易將其想象為使用 Ajax 通過(guò)網(wǎng)絡(luò)動(dòng)態(tài)下載。report 函數(shù)包含所有有趣的代碼,我們來(lái)看看 清單 2。
清單 2. graph 函數(shù)
- function graph(report, maxWidth, maxHeight){
- var data = report.values;
- var canvas = document.getElementById("graph");
- var axisBuffer = 20;
- canvas.height = maxHeight + 100;
- canvas.width = maxWidth;
- var ctx = canvas.getContext("2d");
- var width = 50;
- var buffer = 20;
- var i = 0;
- var x = buffer + axisBuffer;
- ctx.font = "bold 12px sans-serif";
- ctx.textAlign = "start";
- for (i=0;i<data.length;i++){
- ctx.fillStyle = "rgba(0, 0, 200, 0.9)";
- ctx.fillRect(x, maxHeight - (data[i][report.y] / 2),
- width, (data[i][report.y] / 2));
- ctx.fillStyle = "rgba(0, 0, 0, 0.9)";
- ctx.fillText(data[i][report.x], x + (width / 4), maxHeight + 15);
- x += width + buffer;
- }
- // draw the horizontal axis
- ctx.moveTo(axisBuffer, maxHeight);
- ctx.lineTo(axisBuffer+maxWidth, maxHeight);
- ctx.strokeStyle = "black";
- ctx.stroke();
- // draw the vertical axis
- ctx.moveTo(axisBuffer,0);
- ctx.lineTo(axisBuffer,maxHeight);
- ctx.stroke();
- // draw gridlines
- var lineSpacing = 50;
- var numLines = maxHeight/lineSpacing;
- var y = lineSpacing;
- ctx.font = "10px sans-serif";
- ctx.textBaseline = "middle";
- for (i=0;i<numLines;i++){
- ctx.strokeStyle = "rgba(0,0,0,0.25)";
- ctx.moveTo(axisBuffer, y);
- ctx.lineTo(axisBuffer + maxWidth,y);
- ctx.stroke();
- ctx.fillStyle = "rgba(0,0,0, 0.75)";
- ctx.fillText(""+(2*(maxHeight -y)), 0, y);
- y += lineSpacing;
- }
- }
在這個(gè)函數(shù)的第一部分中,您建立了創(chuàng)建這個(gè)報(bào)告需要的對(duì)象,比如畫(huà)布的寬度和高度,填充變量等。您還創(chuàng)建了畫(huà)布上下文對(duì)象,因?yàn)檫@是用于進(jìn)行所有實(shí)際畫(huà)圖的對(duì)象。然后,您通過(guò)迭代報(bào)告數(shù)據(jù),繪制 圖 1 中的柱狀圖。首先,您設(shè)置 fillStyle 屬性。這就像設(shè)置一個(gè)顏色一樣簡(jiǎn)單,您使用 CSS 時(shí)也可能會(huì)這樣做。在本例中,使用 rgba 標(biāo)記來(lái)設(shè)置顏色,以及 alpha 值(這是顏色的透明度,稍后我們討論 奇妙的 CSS3 世界 時(shí)還將介紹這個(gè)參數(shù))。設(shè)置 fillStyle 屬性后,使用 fillRect API 來(lái)為數(shù)據(jù)點(diǎn)創(chuàng)建柱狀圖。這里,您指定這個(gè)矩形的起點(diǎn) (x,y) 以及它的高度和寬度。接下來(lái),您重新定義 fillStyle,因?yàn)槟氪蛴∫恍┪谋荆鳛閳?bào)告的一部分。您使用 fillText API 來(lái)在畫(huà)布上繪制文本。您對(duì)每個(gè)數(shù)據(jù)點(diǎn)都執(zhí)行這個(gè)操作,為每個(gè)數(shù)據(jù)點(diǎn)創(chuàng)建一個(gè)柱狀圖,其下帶有一個(gè)標(biāo)簽。
接下來(lái),您需要繪制這個(gè)圖形的其他部分 — 軸線和網(wǎng)格線。首先,繪制水平和垂直軸線。對(duì)于每條軸線,使用 moveTo API 來(lái)設(shè)置開(kāi)始繪制直線的起始點(diǎn)。然后使用 lineTo API 來(lái)從這個(gè)起始點(diǎn)到傳遞到這個(gè) lineTo 調(diào)用中的端點(diǎn)之間繪制一條直線。注意,這并不實(shí)際繪制一條直線;相反,您調(diào)用 stroke API 來(lái)繪制這條直線。繪制水平和垂直軸線后,沿著它們的標(biāo)簽繪制網(wǎng)格線,方法是均勻間隔它們,然后使用相同的 moveTo、lineTo 和 stroke 組合來(lái)繪制這些直線。
這就是以編程方式創(chuàng)建這個(gè)報(bào)告圖形所需的所有代碼。在這個(gè)示例中,您已經(jīng)看到了許多最重要的、也是最常使用的畫(huà)布 API,但還有其他幾個(gè) API(比如用于繪制曲線)。您可以使用這些 API 完成一些令人驚訝的任務(wù),這些任務(wù)可以在任何基于 Webkit 的瀏覽器上完成。如果您的目標(biāo)不是繪制圖形,HTML 5 仍舊有很多格式為 Cascading Style Sheets (CSS) 3.0 的新視覺(jué)圖像。
奇妙的 CSS3 世界
談到 HTML 5,您可能會(huì)馬上想到 HTML 標(biāo)記。當(dāng)然,HTML 5 肯定包含新標(biāo)記,我們將在下一小節(jié)中查看其中的部分新標(biāo)記。在上一小節(jié)中,您看到了如何使用一個(gè) <canvas> 標(biāo)記來(lái)在 DOM 中創(chuàng)建一個(gè)畫(huà)布對(duì)象。但是,大部分代碼是 JavaScript。HTML 僅僅是 HTML 5 的一部分 — JavaScript 和 CSS 也是同樣重要的部分。HTML 5 中的許多新用戶界面元素由 CSS 標(biāo)準(zhǔn)的最新版 CSS 3.0 提供。在 圖 2 中,一個(gè)使用幾種 CSS 3.0 新技術(shù)的 Web 頁(yè)面出現(xiàn)在基于 Android 的手機(jī)和 iPhone 上。
圖 2. 移動(dòng)設(shè)備的新 CSS 功能
圖 2 在一個(gè)基于 Android 的設(shè)備和 iPhone 上展示了許多新 CSS 功能。左邊的圖像來(lái)自一個(gè)基于 Android 的設(shè)備。它比右邊的圖像更大,原因是它來(lái)自一個(gè) Motorola Droid,它比用于右邊的圖像的 iPhone 3GS 擁有的分辨率更高的屏幕。因此,您在 Droid 上將看到更多的頁(yè)面內(nèi)容。但是,您可能會(huì)看到,標(biāo)題 “The Gettysburg Address” 有一個(gè)倒影,該倒影在 iPhone 上逐漸淡出,但是在 Droid 上并不淡出,而是最終模糊下一個(gè)標(biāo)題。這只是一個(gè)細(xì)節(jié)提醒:即使基于 Android 的設(shè)備和 iPhone 都擁有基于 Webkit 的瀏覽器,但它們之間也有細(xì)微的差別,因此您在測(cè)試時(shí)必須更加細(xì)心。現(xiàn)在看一下生成這個(gè)漂亮頁(yè)面的代碼(見(jiàn) 清單 3),首先從頁(yè)面頂端開(kāi)始。
清單 3. 頁(yè)面上半部分的代碼
- <!DOCTYPE html>
- <html>
- <head>
- <script type="text/javascript">
- function $(id){
- return document.getElementById(id);
- }
- function init(){
- var i=0;
- var row = {};
- var cell = {};
- var topics = ["nth-child", "gradients", "alpha", "text effects",
- "reflections", "transformations"];
- for (i=0;i<topics.length;i++){
- row = document.createElement("tr");
- cell = document.createElement("td");
- cell.appendChild(document.createTextNode(topics[i]));
- row.appendChild(cell);
- $("dtable").appendChild(row);
- }
- }
- </script>
- <style type="text/css">
- header > h1{
- color: yellow;
- background: -webkit-gradient(linear, left top, left bottom,
- from(blue), to(white))
- }
- tr:nth-child(4n+1) { color: navy; }
- tr:nth-child(4n+2) { color: green; }
- tr:nth-child(4n+3) { color: maroon; }
- tr:nth-child(4n+4) { color: purple; }
- input[type="text"]{
- background: rgba(150, 30, 30, 0.5);
- }
- </style>
- </head>
- <body onload="init()">
- <header>
- <h1>The World of CSS3</h1>
- <div>What kind of CSS3 does your browser support?</div>
- </header>
- <table id="dtable"></table>
- <div id="formSection">
- <label for="name">What's your name?</label>
- <input type="text" id="name"></input>
- <button id="rtBtn" onclick="rotate()">Rotate</button>
- </div>
- </body>
- </html>
清單 3 中的代碼繪制標(biāo)題 “Gettysburg Address” 上方的所有 UI。 您將稍后看到這個(gè)頁(yè)面的下半部分的代碼。
首先應(yīng)該檢查頁(yè)面標(biāo)題。如果您查看清單 3 底部附近的 HTML 頁(yè)面主體,您將看到這個(gè)標(biāo)題實(shí)際上位于一個(gè) header 標(biāo)記中 — 這是 HTML 5 中的一個(gè)新 HTML 元素。
現(xiàn)在看看 style 元素(位于 清單 3 中的 HTML 主體上方)。這個(gè)文本的樣式使用帶有選擇器 header > h1 的 CSS 設(shè)置。這個(gè)規(guī)則將文本顏色設(shè)置為黃色,同時(shí)將其背景設(shè)置為藍(lán)色和白色。背景應(yīng)用有漸變。這是您看到的前綴為 -webkit 的 CSS 特性的首個(gè)示例。您可能會(huì)猜測(cè),這個(gè)前綴使這個(gè) CSS 專用于基于 Webkit 的瀏覽器。但是,在多數(shù)情況下,這些特性是 CSS 3.0 標(biāo)準(zhǔn)的一部分,但它們處于這個(gè)標(biāo)準(zhǔn)中還在不斷輕微變化的部分。多數(shù)情況下,Webkit 瀏覽器和基于 Mozilla Firefox 的瀏覽器都已經(jīng)實(shí)現(xiàn)了這些特性。如果您的開(kāi)發(fā)也需要針對(duì) Mozilla 瀏覽器(比如 Firefox 的移動(dòng)版本 Fennec,該版本在歐洲的 Nokia 智能手機(jī)上迅速流行起來(lái)),那么您通常可以將 -webkit 前綴更改為 -moz。
下一步是使用名為 dtable 的表顯示一個(gè)主題列表。如 圖 2 所示,當(dāng)您顯示這個(gè)表的內(nèi)容時(shí),相鄰兩行的顏色各不相同。這個(gè)任務(wù)使用下一個(gè) CSS 部分 — tr:nth-child 聲明 — 來(lái)完成。可以在任意重復(fù)的元素上使用 nth-child 聲明。您傳遞一個(gè)用作謂詞的公式,檢查它是否是一個(gè)有效的元素規(guī)則。在本例中,您聲明表單行號(hào)為 4n+1(1、5、9,等等)的行的顏色為海軍藍(lán),表單行號(hào)為4n+2(2、6、10,等等)的行的顏色為綠色,以此類推,其余的行分別為栗色和紫色。過(guò)去,您經(jīng)常需要對(duì)表、列表等組件實(shí)現(xiàn)類似的視覺(jué)效果,但通常是通過(guò)繁瑣的 JavaScript 來(lái)實(shí)現(xiàn)。
最后的視覺(jué)元素是紅色的文本字段,帶有標(biāo)簽 What's your name? 和按鈕 Rotate。這個(gè)文本字段的紅色是使用一個(gè)特定于類型的輸入選擇器實(shí)現(xiàn)的。換句話說(shuō),這是一個(gè) CSS 規(guī)則,只適用于類型為 text 的輸入元素。現(xiàn)在,您可能想知道 Rotate 按鈕到底作用何在?看看 清單 4 中的代碼就明白了,該代碼調(diào)用一個(gè)名為 rotate 的函數(shù)。
清單 4. 使用 CSS 的 JavaScript rotate 函數(shù)
- function rotate(){
- $("formSection").style["-webkit-transform"] = "rotateZ(-5deg)";
- $("formSection").style["-webkit-transition"] =
- "-webkit-transform 2s ease-in-out";
- $("rtBtn").innerHTML = "Undo";
- $("rtBtn").onclick = function() {
- $("formSection").style["-webkit-transform"] = "";
- $("rtBtn").innerHTML = "Rotate";
- $("rtBtn").setAttribute("onclick", "rotate()");
- }
- }
這個(gè) rotate 函數(shù)使用 JavaScript 來(lái)更改應(yīng)用到名為 formSection 的 div 的 CSS。(注意:您正在將 $() 用作document.getElementById() 的一個(gè)別名。)要旋轉(zhuǎn)這個(gè) div,將它的 -webkit-transform 樣式設(shè)置為 rotateZ(-5deg),將其逆時(shí)針旋轉(zhuǎn) 5 度。接下來(lái),將 -webkit-transform 樣式設(shè)置為 -webkit-transform 2s ease-in-out。這使旋轉(zhuǎn)耗時(shí)兩秒鐘,緩慢啟動(dòng),加速,然后在最后再次減速。在 圖 3 中,左邊顯示 What's your name? 字段旋轉(zhuǎn)之前的初始位置;右邊顯示該字段部分旋轉(zhuǎn)后的視覺(jué)效果及其 Undo 按鈕。
圖 3. 旋轉(zhuǎn) HTML 元素
參見(jiàn) 參考資料 中的鏈接查看這個(gè)效果在 Chrome、Safari 4 和 Opera 等兼容 HTML 5 的瀏覽器上的實(shí)際運(yùn)行情況。
現(xiàn)在我們轉(zhuǎn)到 圖 2 中的頁(yè)面的下半部分。這里您看到幾個(gè)有趣的圖像、文本效果以及布局示例。清單 5 顯示了相關(guān)代碼。
清單 5. 圖 2 的下半部分代碼
- <!DOCTYPE html>
- <html>
- <head>
- <style type="text/css">
- h2 {
- -webkit-text-fill-color: blue;
- -webkit-text-stroke-color: yellow;
- -webkit-text-stroke-width: 1.5px;
- background: -webkit-gradient(radial, 430 50, 0, 430 50, 200, from(red),
- to(#000));
- -webkit-box-reflect:below 5px -webkit-gradient(linear, left top, left
- bottom, from(transparent), color-stop(0.5, transparent), to(white));
- }
- h3{
- color: rgba(0,0,255,0.75);
- background: rgba(255,255,0,0.5);
- }
- .xyz{
- text-shadow: #6374AB 4px -4px 2px;
- white-space: nowrap;
- width: 14em;
- height: 2em;
- overflow: hidden;
- text-overflow: ellipsis;
- border: 1px solid #bbb;
- border-radius: 9px;
- background-color: #fff;
- }
- .abc {
- border: 1px solid #000;
- border-radius: 9px;
- -webkit-column-count:4;
- -webkit-column-rule: 1px solid #a00;
- -webkit-column-gap: 0.75em;
- }
- </style>
- </head>
- <body onload="init()">
- <h2>The Gettysburg Address</h2>
- <h3>Abraham Lincoln, Gettysburg, PA. November 19, 1863</h3>
- <div class="xyz">
- Four score and seven years ago our fathers brought forth on this
- continent a new nation, conceived in liberty, and dedicated to
- the proposition that all men are created equal.
- </div>
- <div class="abc">
- Now we are engaged in a great civil war, testing whether that
- nation, or any nation, so conceived and so dedicated, can long
- endure. We are met on a great battle-field of that war. We have
- come to dedicate a portion of that field, as a final resting
- place for those who here gave their lives that that nation might
- live. It is altogether fitting and proper that we should do this.
- </div>
- </body>
- </html>
我們來(lái)逐個(gè)看看這個(gè)代碼中的元素。首先,為 “The Gettysburg Address” 創(chuàng)建了一個(gè)標(biāo)題,并以幾種方式設(shè)置其樣式。
- 使用 -webkit-text-fill-color、-webkit-text-stroke-color 和 -webkit-text-stroke-width 樣式來(lái)創(chuàng)建 “黃中帶藍(lán)” 的效果。
- 通過(guò)設(shè)置背景樣式 -webkit-gradient 來(lái)在文本后面放置一個(gè)紅黑色背景。注意,這是一個(gè)放射狀漸變,而此前您看到的是一個(gè)線性漸變。這兩種漸變?cè)谥悄苁謾C(jī)上的效果都很好。
- 通過(guò)設(shè)置 -webkit-box-reflect 樣式對(duì)標(biāo)題應(yīng)用一個(gè)倒影。設(shè)置這個(gè)樣式以在標(biāo)題下方 5 個(gè)像素處反射標(biāo)題,并對(duì)倒影應(yīng)用一個(gè)漸變效果。這里的漸變效果使倒影看起來(lái)似乎正在淡出。如果回顧一下 圖 2,您將看到,Android 瀏覽器不支持這個(gè)對(duì)倒影應(yīng)用一個(gè)漸變的組合:它只是呈現(xiàn)不帶任何漸變的倒影。
繼續(xù)移動(dòng)到下一個(gè)標(biāo)題,對(duì)它應(yīng)用一個(gè)非常簡(jiǎn)單的樣式:文本一種顏色,背景另一種顏色。這兩種顏色都使用 rgba 函數(shù)來(lái)指定 “紅-綠-藍(lán)” 值,以及一個(gè) alpha 透明度值。值 1.0 完全不透明,值 0.0 則為透明。
清單 5 中的下一部分是這篇短文的第一段。文本周圍有一個(gè)邊界,您使用新的 border-radius 樣式來(lái)實(shí)現(xiàn) 4 個(gè)圓角。現(xiàn)在,您在 Web 上到處都能看到這樣的圓角,它們通常使用圖像來(lái)實(shí)現(xiàn)。與使用 CSS 3.0 來(lái)實(shí)現(xiàn)相比,這種方法真是太老土了。通過(guò)使用 text-shadow 樣式來(lái)向這個(gè)段落的文本應(yīng)用一個(gè)陰影。最后,注意段落區(qū)域受到了父 div 的高度和寬度的限制,文本太大了。與在一些較老的瀏覽器中看到的那樣直接截除文本相反,通過(guò)設(shè)置 text-overflow 樣式可以獲得一個(gè)美觀的省略號(hào)(...)效果。
最后,來(lái)到文本的最后部分。它的周圍也有一個(gè)邊界,但是注意,它出現(xiàn)在 4 個(gè)帶有列分隔符的列中。為此,設(shè)置 -webkit-column-count 樣式,并設(shè)置配套的 -webkit-column-rule 樣式來(lái)獲取這些分隔符。可以想見(jiàn),如果沒(méi)有這些新的 CSS 3.0 特性,像這樣格式化文本將會(huì)是多么的繁瑣!當(dāng)您創(chuàng)建簡(jiǎn)單的 headers 和 footers(它們二者也是 HTML 5 中的新元素)時(shí),這也可能是一個(gè)很有用的特性。看一下它們以及由 HTML 5 引入的其他一些新標(biāo)記。
新語(yǔ)義
HTML 5 向 HTML 標(biāo)記添加了許多新元素。其中一些元素將導(dǎo)致瀏覽器提供一些新的呈現(xiàn)處理。其他一些元素將添加一些稍后可以通過(guò) JavaScript 變得可用的額外特性。但是,另外一些元素則不具備上述兩種功能。它們與 <span>、<div> 和 <p> 看起來(lái)一樣,且擁有相同的編程接口。但是,它們將添加額外的語(yǔ)義含義。這些新語(yǔ)義對(duì)于頁(yè)面的非視覺(jué)用戶(包括使用屏幕閱讀器這樣的輔助技術(shù)的用戶)和搜索引擎爬蟲(chóng)這樣的計(jì)算機(jī)程序很重要。這些新標(biāo)記還向開(kāi)發(fā)人員提供一些掛鉤,幫助他們編寫表現(xiàn)力更強(qiáng)的 CSS 選擇器。圖 4 展示了一個(gè)使用一些新語(yǔ)義元素的 Web 頁(yè)面。
圖 4. iPhone 上的一些新 HTML 5 元素
圖 4 中的這個(gè)示例擁有一個(gè) header 元素、幾個(gè) nav 元素、一個(gè) article 元素、一個(gè) section 元素、以及一個(gè) aside 元素。這些元素不會(huì)導(dǎo)致任何特殊呈現(xiàn)。它們只是添加語(yǔ)義值,您可以使用它們來(lái)編寫向它們提供視覺(jué)處理來(lái)匹配該語(yǔ)義值的 CSS。圖 4 中顯示的圖片的代碼如 清單 6 所示。
清單 6. HTML 5 中的新語(yǔ)義元素
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <meta name="viewport" content="width=device-width; initial-scale=1.0;
- maximum-scale=1.0; user-scalable=0;"/>
- <meta name="apple-touch-fullscreen" content="YES" />
- <title>Get the latest markup</title>
- </head>
- <body>
- <header style="border: 1px dotted #000;border-radius: 3px;">
- <hgroup align="center">
- <h1>Real documents have headers</h1>
- <h2>Even if they don't say so</h2>
- </hgroup>
- <hgroup>
- <nav style="-webkit-column-count:3;-webkit-column-rule: 1px solid #a00;">
- <a href="new-css.html">CSS3</a><br/>
- <a href="report.html">Canvas</a><br/>
- <a href="elements.html">Markup</a>
- </nav>
- </hgroup>
- </header>
- <article>
- <h1>There are a lot of new markup elements in HTML5</h1>
- <time datetime="2010-05-16" pubdate>Sunday, May 16</time>
- <section>Did you notice that we just had two H1's?
- But it's cool!</section>
- <aside style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" >
- If this page was really popular, I'd put an ad here and make some
- serious cash
- </aside>
- </article>
- </body>
- </html>
您可以看到此前提到過(guò)的幾個(gè)新元素。注意,您還應(yīng)用了一些新的 CSS 樣式來(lái)在 header 周圍創(chuàng)建一個(gè)圓角框,并為 nav 創(chuàng)建幾個(gè)分隔符。您還在 aside 上使用了文本溢出樣式。這里的關(guān)鍵點(diǎn)是:無(wú)需額外的工作,您就可以創(chuàng)建更有意義的標(biāo)記,然后,您可以像使用了 <div> 和 <span> 一樣顯示該標(biāo)記。要查看擁有更多視覺(jué)和編程效果的新 HTML 5 元素的一個(gè)示例,請(qǐng)看 圖 5。(查看圖 5 的 文本版本。)
圖 5. 在 iPhone 上使用 HTML 5 創(chuàng)建的表單
圖 5 中的屏幕使用了在 HTML 5 中可用的許多新表單元素。在很多情況下,這些元素看起來(lái)就像現(xiàn)有的元素,但您可以期望瀏覽器添加這些更豐富的表單元素的更好的視覺(jué)表示。為展示大致效果,圖 6 顯示了上述表單元素在 Opera 桌面瀏覽器中的效果。(查看圖 6 的 文本版本。)
圖 6. Opera 上的 HTML 5 表單元素
Opera 一直是實(shí)現(xiàn) HTML 5 特性的先行者,這對(duì)于新的表單元素而言尤其如此。現(xiàn)在,看看生成 清單 4 和 清單 5 的代碼,以便您更好地理解 Opera 之所以采用其呈現(xiàn)方式的原因。清單 7 顯示了這個(gè)代碼。
清單 7. 代碼形式的 HTML 5 表單元素
- <form id="settings">
- <fieldset id="inputs" style="border: 1px solid #000;border-radius: 6px;">
- <legend>Settings</legend>
- <label for="name">Username</label>
- <input id="name" name="name" type="text" required autofocus /><br/>
- <label for="name">Name</label>
- <input id="name" name="name" type="text"
- placeholder="First and last name" required /><br/>
- <label for="email">Email</label>
- <input id="email" name="email" type="email"
- placeholder="example@domain.com" required /><br/>
- <label for="phone">Phone</label>
- <input id="phone" name="phone" type="tel"
- placeholder="Eg. +447500000000" required /><br/>
- <label for="dob">Date of birth</label>
- <input id="dob" name="dob" type="date" required/>
- <fieldset style="border: 1px dotted #000; border-radius: 6px">
- <legend>Preferred Contact Method</legend>
- <ol>
- <li>
- <input id="emailMeth" name="contactMethod"
- type="radio">
- <label for="emailMeth">Email</label>
- </li>
- <li>
- <input id="phoneMeth" name="contactMethod"
- type="radio">
- <label for="phoneMeth">Phone</label>
- </li>
- </ol>
- </fieldset>
- <label for="climate">Preferred external temperature</label>
- <input id="climate" name="climate" type="range" min="50"
- max="100" step="5" value="70"/><br/>
- <label for="color">Favorite color</label>
- <input id="color" name="color" type="color"/><br/>
- <label for="referrer">Where'd you hear about us?</label>
- <input type="url" name="refUrl" id="referrer" list="urls"/>
- <datalist id="urls">
- <option label="TechCrunch" value="http://www.techcrunch.com/">
- <option label="ReadWrite Web" value="http://www.readwriteweb.com/">
- <option label="Engadget" value="http://www.engadget.com/">
- <option label="Ajaxian" value="http://www.ajaxian.com/">
- </datalist><br/>
- <button type="button" onclick="checkInputs()">Save</button>
- </fieldset>
- </form>
清單 7 中的 form 元素展示了 HTML 5 的許多新特性。注意兩個(gè)新屬性:required 和 autofocus。required 屬性用于表單驗(yàn)證(下面將詳細(xì)介紹)過(guò)程中,autofocus 屬性允許選擇頁(yè)面上的元素以獲取焦點(diǎn)。還要注意幾個(gè)擁有 placeholder 文本的元素。這是許多網(wǎng)站多年來(lái)一直在使用的一個(gè)模式 — 將某個(gè)示例或解釋性文本放置到一個(gè)文本框中 — 但開(kāi)發(fā)人員總是必須修改(hack)該代碼。圖 4展示了 iPhone 如何整潔地實(shí)現(xiàn)這個(gè)模式。
下面,您將看到一些支持輸入元素的新類型,比如 email, phone, date, range, color, 和 url。現(xiàn)在, 這些類型在 iPhone 和 Android 瀏覽器上總是呈現(xiàn)為文本字段,但那只是使用語(yǔ)義不太準(zhǔn)確的 HTML 4.0 創(chuàng)建它們的樣子。圖 5 展示了它們未來(lái)的可能外觀。date 輸入在 Opera 上展示其新 UI(一個(gè)彈出式日歷)前必須獲得焦點(diǎn)。這對(duì)于 圖 7 中的 url 輸入也同樣適用,但原因不在于它是 url 輸入,而是它擁有一個(gè) list 屬性。該屬性指向 datalist 元素,該元素包含該字段支持的值。當(dāng)您聚焦該字段時(shí),您將看到來(lái)自 datalist 的可能值 (本例中是幾個(gè) URL)。圖 7 展示了 date 和 datalist 特性。
圖 7. 帶有日期和數(shù)據(jù)列表的 HTML 5 輸入
隨著 Webkit 持續(xù)快速發(fā)展,可以預(yù)見(jiàn),許多輸入類型將允許更有用的視覺(jué)表示。Opera 將為您帶來(lái)更好的未來(lái)。許多這些輸入字段也提供驗(yàn)證,HTML 5 擁有一組完整的新驗(yàn)證 APIs。這些特性目前還沒(méi)有在 iPhone 或基于 Android 的設(shè)備上實(shí)現(xiàn),但已經(jīng)在它們的桌面對(duì)等設(shè)備上實(shí)現(xiàn),因此,預(yù)計(jì)可以很快在移動(dòng)瀏覽器上實(shí)現(xiàn)這些特性。清單 8 展示了這些新的驗(yàn)證 APIs 的使用情況。
清單 8. HTML 5 驗(yàn)證 APIs 的應(yīng)用
- function checkInputs(){
- var inputs = document.getElementById("inputs").childNodes;
- var len = inputs.length;
- var i = 0;
- var input = null;
- var errors = [];
- for (i=0;i<len;i++){
- input = inputs.item(i);
- if (input.nodeName == "INPUT"){
- if (input.validity){
- if (!input.checkValidity()){
- errors.push(input.validationMessage);
- }
- }
- }
- }
- var errMsg = "There are " + errors.length + " errors";
- var notify = function(){
- var notification =
- webkitNotifications.createNotification(null, "Errors!", errMsg);
- notification.show();
- };
- if (window.webkitNotifications){
- if (webkitNotifications.checkPermission()){
- webkitNotifications.requestPermission(notify);
- } else {
- notify();
- }
- } else {
- alert(errMsg);
- }
- }
每個(gè)輸入元素 擁有一個(gè) validity 屬性。可以使用這個(gè)屬性,或者,也可以使用返回 ture 或 false 的 checkValidity() 函數(shù)以及validationMessage 屬性來(lái)獲取一條本地錯(cuò)誤消息。在本文撰寫之時(shí),多數(shù)最新的桌面瀏覽器并不能為 validationMessage 返回任何一致或標(biāo)準(zhǔn)的消息,因此,它的用途有限。validity 對(duì)象可用于檢查不同類型的錯(cuò)誤,比如valueMissing、rangeOverflow、rangeUnderflow、patternMismatch 和 tooLong。例如,如果元素?fù)碛幸粋€(gè)必要屬性而用戶留空,那么 validity.valueMissing 將為 true。
最后,注意,在 清單 8 中,您在明確所有的驗(yàn)證錯(cuò)誤之后,將嘗試使用 webkitNotifications。這些通知與您的桌面計(jì)算機(jī)上的通知類似,可用于最新版 Chrome 中。因此,您同樣可以期望它們將很快應(yīng)用于 iPhone 和 Android 瀏覽器。API 的使用很簡(jiǎn)單明了。惟一需要注意的是,您需要檢查用戶是否已提供您的站點(diǎn)許可來(lái)使用這個(gè) API。如果沒(méi)有,您必須請(qǐng)求許可;反之,則傳遞想要被調(diào)用的函數(shù)。
結(jié)束語(yǔ)
在本文中,您快速瀏覽了 HTML 5 中許多與 UI 相關(guān)的新特性:從新元素到新樣式再到繪圖畫(huà)布。這些特性(除了文末提到的幾個(gè)例外之外)都可用于 iPhone 和基于 Android 設(shè)備上發(fā)現(xiàn)的基于 Webkit 的瀏覽器上。Blackberry 和 Nokia 智能手機(jī)等其他流行平臺(tái)即將裝配強(qiáng)大的瀏覽器,以便利用本文介紹的這些技術(shù)。作為一位移動(dòng) Web 開(kāi)發(fā)人員,您有機(jī)會(huì)使用這些強(qiáng)大的視覺(jué)特性來(lái)瞄準(zhǔn)廣泛的用戶,這些特性比桌面瀏覽器上使用 HTML、CSS 和 JavaScript 實(shí)現(xiàn)的任何特性都要強(qiáng)大。在本系列前 4 篇文章中,您了解到可用于這些精彩的新移動(dòng)瀏覽器上的許多其他新技術(shù)(比如地理定位和 Web Workers)。移動(dòng) Web 并不是您多年來(lái)一直為之編程的 Web 的簡(jiǎn)化版,而是更強(qiáng)大的、擁有無(wú)限可能性的版本。