HTML5移动应用开发第5章:新的可视化UI 特性

时间:2014-09-14

先决条件

在本文中,您将使用最新的 Web 技术开发 Web 应用程序。这里的大部分代码只是 HTML、JavaScript 和 CSS — 所有 Web 发人员的核心技术。所需的最重要的工具是用于进行测试的浏览器。本文大部分代码将在最新桌面浏览器上运行,但也有一些例外,我们将在文章中进行说明。当然,您也必须在移动浏览器上测试,为此,您需要最新的 iPhone 和 Android SDKs。本文将使用 iPhone SDK 3.1.3 和 Android SDK 2.1。参见 参考资料 获取链接。

通过 Canvas 实现图形效果

多年以来,Web 开发人员一直在抱怨 Canvas。现在,为何还有人会抱怨浏览器中的一个原生画图 API 呢?毕竟,它允许您创建某种图形界面,否则您将需要某种浏览器插件(每位移动 Web 开发人员都知道,插件在一些最流行的移动浏览器上并不可用)。Web 开发人员抱怨 Canvas 的原因是:尽管现在它可用于 Firefox 和 Safari 已经很多年,但最流行的桌面浏览器 Microsoft®Internet Explorer® 一直不支持它。甚至 Internet Explorer 9 的早期版本也不支持 Canvas。因此,多年来,Canvas 一直是最大的技术笑话。您可能会发现,这些令人惊叹的 Canvas 样例遍布整个 Internet,但您不能仅仅因为 Internet Explorer 不支持它就将它用于大多数 Web 应用程序。幸运的是,对于移动 Web 开发人员来说,Canvas 没有这样的限制。您瞄准的所有基于 Webkit 的浏览器都能实现 Canvas 并极大地优化其性能。

Canvas API 是一个低级画图 API,它支持创建直线、曲线、多边形和圆圈,并用彩色、渐变色等填充它们。在 Canvas 上,您可以创建文本,执行各种各样的几何转换。可以想见,这样的 API 的用途是无限的。我们来看一个使用 Canvas 来创建一个图形报告的应用程序。图 1 展示了该应用程序的屏幕截图:一个显示每年结果的柱状图。


图 1. 运行在 Android 浏览器上的基于 Canvas 的报告应用程序
运行在 Android 浏览器上的基于 Canvas 的报告应用程序的屏幕截图 

图 1 所显示的并不是浏览器中的一幅静态图像。这个报告图形是使用这个 Canvas API 实时生成的。清单 1 展示了创建这个报告的 HTML。


清单 1. 报告 HTML

XML/HTML Code复制内容到剪贴板
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  5.     <meta name="viewport" content="width=device-width; initial-scale=1.0;   
  6.         maximum-scale=1.0; user-scalable=0;"/>  
  7.     <meta name="apple-touch-fullscreen" content="YES" />  
  8.     <title>HTML 5 Reports</title>  
  9.     <script type="text/javascript">  
  10.         function init(){  
  11.             var data = [{year : "2007",sales : 49},  
  12.                 {year : "2008",sales : 131},  
  13.                 {year : "2009",sales : 294},   
  14.                 {year : "2010",sales : 405}];  
  15.             var report = {x : "year",  
  16.                     y : "sales",  
  17.                     values : data};  
  18.             graph(report, 350, 300);  
  19.         }  
  20.     </script>  
  21. </head>  
  22. <body onload="init()">  
  23.     <canvas id="graph"></canvas>  
  24. </body>  
  25. </html>      

 

这个清单展示了基本的 HTML 结构。这个文档的主体拥有一个单一的 canvas 标记。在 init 函数(在文档主体加载时调用)中,您定义静态数据(报告数据)并将其传递到 graph 函数。尽管这里将报告定义为静态数据,但很容易将其想象为使用 Ajax 通过网络动态下载。report 函数包含所有有趣的代码,我们来看看 清单 2。


清单 2. graph 函数

JavaScript Code复制内容到剪贴板
  1. function graph(report, maxWidth, maxHeight){  
  2.     var data = report.values;  
  3.     var canvas = document.getElementById("graph");  
  4.     var axisBuffer = 20;  
  5.     canvas.height = maxHeight + 100;  
  6.     canvas.width = maxWidth;  
  7.     var ctx = canvas.getContext("2d");  
  8.   
  9.     var width = 50;  
  10.     var buffer = 20;  
  11.     var i = 0;  
  12.     var x = buffer + axisBuffer;  
  13.     ctx.font = "bold 12px sans-serif";  
  14.     ctx.textAlign = "start";  
  15.     for (i=0;i<data.length;i++){  
  16.         ctx.fillStyle = "rgba(0, 0, 200, 0.9)";  
  17.         ctx.fillRect(x, maxHeight - (data[i][report.y] / 2),   
  18.                  width, (data[i][report.y] / 2));  
  19.         ctx.fillStyle = "rgba(0, 0, 0, 0.9)";  
  20.         ctx.fillText(data[i][report.x], x + (width / 4), maxHeight + 15);  
  21.         x += width + buffer;  
  22.     }  
  23.   
  24.     // draw the horizontal axis  
  25.     ctx.moveTo(axisBuffer, maxHeight);  
  26.     ctx.lineTo(axisBuffer+maxWidth, maxHeight);  
  27.     ctx.strokeStyle = "black";  
  28.     ctx.stroke();  
  29.   
  30.     // draw the vertical axis  
  31.     ctx.moveTo(axisBuffer,0);  
  32.     ctx.lineTo(axisBuffer,maxHeight);  
  33.     ctx.stroke();  
  34.   
  35.     // draw gridlines  
  36.     var lineSpacing = 50;  
  37.     var numLines = maxHeight/lineSpacing;  
  38.     var y = lineSpacing;  
  39.     ctx.font = "10px sans-serif";  
  40.     ctx.textBaseline = "middle";  
  41.     for (i=0;i<numLines;i++){  
  42.         ctx.strokeStyle = "rgba(0,0,0,0.25)";  
  43.         ctx.moveTo(axisBuffer, y);  
  44.         ctx.lineTo(axisBuffer + maxWidth,y);  
  45.         ctx.stroke();  
  46.         ctx.fillStyle = "rgba(0,0,0, 0.75)";  
  47.         ctx.fillText(""+(2*(maxHeight -y)), 0, y);  
  48.         y += lineSpacing;   
  49.     }  
  50. }  

 

在这个函数的第一部分中,您建立了创建这个报告需要的对象,比如画布的宽度和高度,填充变量等。您还创建了画布上下文对象,因为这是用于进行所有实际画图的对象。然后,您通过迭代报告数据,绘制 图 1 中的柱状图。首先,您设置 fillStyle 属性。这就像设置一个颜色一样简单,您使用 CSS 时也可能会这样做。在本例中,使用 rgba 标记来设置颜色,以及 alpha 值(这是颜色的透明度,稍后我们讨论 奇妙的 CSS3 世界 时还将介绍这个参数)。设置 fillStyle 属性后,使用 fillRect API 来为数据点创建柱状图。这里,您指定这个矩形的起点 (x,y) 以及它的高度和宽度。接下来,您重新定义 fillStyle,因为您想打印一些文本,作为报告的一部分。您使用 fillText API 来在画布上绘制文本。您对每个数据点都执行这个操作,为每个数据点创建一个柱状图,其下带有一个标签。

接下来,您需要绘制这个图形的其他部分 — 轴线和网格线。首先,绘制水平和垂直轴线。对于每条轴线,使用 moveTo API 来设置开始绘制直线的起始点。然后使用 lineTo API 来从这个起始点到传递到这个 lineTo 调用中的端点之间绘制一条直线。注意,这并不实际绘制一条直线;相反,您调用 stroke API 来绘制这条直线。绘制水平和垂直轴线后,沿着它们的标签绘制网格线,方法是均匀间隔它们,然后使用相同的 moveTo、lineTo 和 stroke 组合来绘制这些直线。

这就是以编程方式创建这个报告图形所需的所有代码。在这个示例中,您已经看到了许多最重要的、也是最常使用的画布 API,但还有其他几个 API(比如用于绘制曲线)。您可以使用这些 API 完成一些令人惊讶的任务,这些任务可以在任何基于 Webkit 的浏览器上完成。如果您的目标不是绘制图形,HTML 5 仍旧有很多格式为 Cascading Style Sheets (CSS) 3.0 的新视觉图像。

奇妙的 CSS3 世界

谈到 HTML 5,您可能会马上想到 HTML 标记。当然,HTML 5 肯定包含新标记,我们将在下一小节中查看其中的部分新标记。在上一小节中,您看到了如何使用一个 <canvas> 标记来在 DOM 中创建一个画布对象。但是,大部分代码是 JavaScript。HTML 仅仅是 HTML 5 的一部分 — JavaScript 和 CSS 也是同样重要的部分。HTML 5 中的许多新用户界面元素由 CSS 标准的最新版 CSS 3.0 提供。在 图 2 中,一个使用几种 CSS 3.0 新技术的 Web 页面出现在基于 Android 的手机和 iPhone 上。


图 2. 移动设备的新 CSS 功能
比较 Android 和 iPhone 移动设备上的新 CSS 功能的屏幕截图 

图 2 在一个基于 Android 的设备和 iPhone 上展示了许多新 CSS 功能。左边的图像来自一个基于 Android 的设备。它比右边的图像更大,原因是它来自一个 Motorola Droid,它比用于右边的图像的 iPhone 3GS 拥有的分辨率更高的屏幕。因此,您在 Droid 上将看到更多的页面内容。但是,您可能会看到,标题 “The Gettysburg Address” 有一个倒影,该倒影在 iPhone 上逐渐淡出,但是在 Droid 上并不淡出,而是最终模糊下一个标题。这只是一个细节提醒:即使基于 Android 的设备和 iPhone 都拥有基于 Webkit 的浏览器,但它们之间也有细微的差别,因此您在测试时必须更加细心。现在看一下生成这个漂亮页面的代码(见 清单 3),首先从页面顶端开始。


清单 3. 页面上半部分的代码

XML/HTML Code复制内容到剪贴板
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <script type="text/javascript">  
  5.         function $(id){  
  6.             return document.getElementById(id);  
  7.         }  
  8.         function init(){  
  9.             var i=0;  
  10.             var row = {};  
  11.             var cell = {};  
  12.             var topics = ["nth-child", "gradients", "alpha", "text effects",   
  13.                           "reflections", "transformations"];  
  14.             for (i=0;i<topics.length;i++){  
  15.                 row = document.createElement("tr");  
  16.                 cell = document.createElement("td");  
  17.                 cell.appendChild(document.createTextNode(topics[i]));  
  18.                 row.appendChild(cell);  
  19.                 $("dtable").appendChild(row);  
  20.             }  
  21.         }  
  22.     </script>  
  23.     <style type="text/css">  
  24.         header > h1{  
  25.             color: yellow;  
  26.             background: -webkit-gradient(linear, left top, left bottom,   
  27.                              from(blue), to(white))  
  28.         }  
  29.         tr:nth-child(4n+1) { color: navy; }  
  30.         tr:nth-child(4n+2) { color: green; }  
  31.         tr:nth-child(4n+3) { color: maroon; }  
  32.         tr:nth-child(4n+4) { color: purple; }  
  33.   
  34.         input[type="text"]{  
  35.             background: rgba(150, 30, 30, 0.5);  
  36.         }  
  37.     </style>  
  38. </head>  
  39. <body onload="init()">  
  40.     <header>  
  41.         <h1>The World of CSS3</h1>  
  42.         <div>What kind of CSS3 does your browser support?</div>  
  43.     </header>  
  44.     <table id="dtable"></table>  
  45.     <div id="formSection">  
  46.         <label for="name">What's your name?</label>  
  47.         <input type="text" id="name"></input>  
  48.         <button id="rtBtn" onclick="rotate()">Rotate</button>  
  49.     </div>  
  50. </body>  
  51. </html>  

 

清单 3 中的代码绘制标题 “Gettysburg Address” 上方的所有 UI。 您将稍后看到这个页面的下半部分的代码。

首先应该检查页面标题。如果您查看清单 3 底部附近的 HTML 页面主体,您将看到这个标题实际上位于一个 header 标记中 — 这是 HTML 5 中的一个新 HTML 元素。

现在看看 style 元素(位于 清单 3 中的 HTML 主体上方)。这个文本的样式使用带有选择器 header > h1 的 CSS 设置。这个规则将文本颜色设置为黄色,同时将其背景设置为蓝色和白色。背景应用有渐变。这是您看到的前缀为 -webkit 的 CSS 特性的首个示例。您可能会猜测,这个前缀使这个 CSS 专用于基于 Webkit 的浏览器。但是,在多数情况下,这些特性是 CSS 3.0 标准的一部分,但它们处于这个标准中还在不断轻微变化的部分。多数情况下,Webkit 浏览器和基于 Mozilla Firefox 的浏览器都已经实现了这些特性。如果您的开发也需要针对 Mozilla 浏览器(比如 Firefox 的移动版本 Fennec,该版本在欧洲的 Nokia 智能手机上迅速流行起来),那么您通常可以将 -webkit 前缀更改为 -moz。

下一步是使用名为 dtable 的表显示一个主题列表。如 图 2 所示,当您显示这个表的内容时,相邻两行的颜色各不相同。这个任务使用下一个 CSS 部分 — tr:nth-child 声明 — 来完成。可以在任意重复的元素上使用 nth-child 声明。您传递一个用作谓词的公式,检查它是否是一个有效的元素规则。在本例中,您声明表单行号为 4n+1(1、5、9,等等)的行的颜色为海军蓝,表单行号为4n+2(2、6、10,等等)的行的颜色为绿色,以此类推,其余的行分别为栗色和紫色。过去,您经常需要对表、列表等组件实现类似的视觉效果,但通常是通过繁琐的 JavaScript 来实现。

最后的视觉元素是红色的文本字段,带有标签 What's your name? 和按钮 Rotate。这个文本字段的红色是使用一个特定于类型的输入选择器实现的。换句话说,这是一个 CSS 规则,只适用于类型为 text 的输入元素。现在,您可能想知道 Rotate 按钮到底作用何在?看看 清单 4 中的代码就明白了,该代码调用一个名为 rotate 的函数。


清单 4. 使用 CSS 的 JavaScript rotate 函数

JavaScript Code复制内容到剪贴板
  1. function rotate(){  
  2.     $("formSection").style["-webkit-transform"] = "rotateZ(-5deg)";  
  3.     $("formSection").style["-webkit-transition"] =   
  4.           "-webkit-transform 2s ease-in-out";  
  5.     $("rtBtn").innerHTML = "Undo";  
  6.     $("rtBtn").onclick = function() {  
  7.         $("formSection").style["-webkit-transform"] = "";  
  8.         $("rtBtn").innerHTML = "Rotate";  
  9.         $("rtBtn").setAttribute("onclick""rotate()");  
  10.     }  
  11. }  

 

这个 rotate 函数使用 JavaScript 来更改应用到名为 formSection 的 div 的 CSS。(注意:您正在将 $() 用作document.getElementById() 的一个别名。)要旋转这个 div,将它的 -webkit-transform 样式设置为 rotateZ(-5deg),将其逆时针旋转 5 度。接下来,将 -webkit-transform 样式设置为 -webkit-transform 2s ease-in-out。这使旋转耗时两秒钟,缓慢启动,加速,然后在最后再次减速。在 图 3 中,左边显示 What's your name? 字段旋转之前的初始位置;右边显示该字段部分旋转后的视觉效果及其 Undo 按钮。


图 3. 旋转 HTML 元素
在一个移动设备上旋转 HTML 元素的屏幕截图 

参见 参考资料 中的链接查看这个效果在 Chrome、Safari 4 和 Opera 等兼容 HTML 5 的浏览器上的实际运行情况。

现在我们转到 图 2 中的页面的下半部分。这里您看到几个有趣的图像、文本效果以及布局示例。清单 5 显示了相关代码。


清单 5. 图 2 的下半部分代码

XML/HTML Code复制内容到剪贴板
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <style type="text/css">  
  5.         h2 {  
  6.             -webkit-text-fill-color: blue;  
  7.             -webkit-text-stroke-color: yellow;  
  8.             -webkit-text-stroke-width: 1.5px;  
  9.             background: -webkit-gradient(radial, 430 50, 0, 430 50, 200, from(red),   
  10. to(#000));  
  11.             -webkit-box-reflect:below 5px -webkit-gradient(linear, left top, left   
  12. bottom, from(transparent), color-stop(0.5, transparent), to(white));  
  13.         }  
  14.         h3{  
  15.             color: rgba(0,0,255,0.75);  
  16.             background: rgba(255,255,0,0.5);  
  17.         }  
  18.         .xyz{  
  19.             text-shadow: #6374AB 4px -4px 2px;  
  20.             white-space: nowrap;  
  21.             width: 14em;   
  22.             height: 2em;   
  23.             overflow: hidden;  
  24.             text-overflow: ellipsis;   
  25.             border: 1px solid #bbb;   
  26.             border-radius: 9px;               
  27.             background-color: #fff;  
  28.         }  
  29.         .abc {  
  30.             border: 1px solid #000;  
  31.             border-radius: 9px;          
  32.             -webkit-column-count:4;  
  33.             -webkit-column-rule: 1px solid #a00;  
  34.             -webkit-column-gap: 0.75em;  
  35.         }  
  36.     </style>  
  37. </head>  
  38. <body onload="init()">  
  39.     <h2>The Gettysburg Address</h2>  
  40.     <h3>Abraham Lincoln, Gettysburg, PA. November 19, 1863</h3>  
  41.     <div class="xyz">  
  42.         Four score and seven years ago our fathers brought forth on this   
  43.         continent a new nation, conceived in liberty, and dedicated to   
  44.             the proposition that all men are created equal.  
  45.     </div>  
  46.     <div class="abc">  
  47.         Now we are engaged in a great civil war, testing whether that   
  48.             nation, or any nation, so conceived and so dedicated, can long   
  49.             endure. We are met on a great battle-field of that war. We have   
  50.             come to dedicate a portion of that field, as a final resting   
  51.             place for those who here gave their lives that that nation might   
  52.             live. It is altogether fitting and proper that we should do this.  
  53.     </div>  
  54. </body>  
  55. </html>  

 

我们来逐个看看这个代码中的元素。首先,为 “The Gettysburg Address” 创建了一个标题,并以几种方式设置其样式。

  1. 使用 -webkit-text-fill-color、-webkit-text-stroke-color 和 -webkit-text-stroke-width 样式来创建 “黄中带蓝” 的效果。
  2. 通过设置背景样式 -webkit-gradient 来在文本后面放置一个红黑色背景。注意,这是一个放射状渐变,而此前您看到的是一个线性渐变。这两种渐变在智能手机上的效果都很好。
  3. 通过设置 -webkit-box-reflect 样式对标题应用一个倒影。设置这个样式以在标题下方 5 个像素处反射标题,并对倒影应用一个渐变效果。这里的渐变效果使倒影看起来似乎正在淡出。如果回顾一下 图 2,您将看到,Android 浏览器不支持这个对倒影应用一个渐变的组合:它只是呈现不带任何渐变的倒影。

继续移动到下一个标题,对它应用一个非常简单的样式:文本一种颜色,背景另一种颜色。这两种颜色都使用 rgba 函数来指定 “红-绿-蓝” 值,以及一个 alpha 透明度值。值 1.0 完全不透明,值 0.0 则为透明。

清单 5 中的下一部分是这篇短文的第一段。文本周围有一个边界,您使用新的 border-radius 样式来实现 4 个圆角。现在,您在 Web 上到处都能看到这样的圆角,它们通常使用图像来实现。与使用 CSS 3.0 来实现相比,这种方法真是太老土了。通过使用 text-shadow 样式来向这个段落的文本应用一个阴影。最后,注意段落区域受到了父 div 的高度和宽度的限制,文本太大了。与在一些较老的浏览器中看到的那样直接截除文本相反,通过设置 text-overflow 样式可以获得一个美观的省略号(...)效果。

最后,来到文本的最后部分。它的周围也有一个边界,但是注意,它出现在 4 个带有列分隔符的列中。为此,设置 -webkit-column-count 样式,并设置配套的 -webkit-column-rule 样式来获取这些分隔符。可以想见,如果没有这些新的 CSS 3.0 特性,像这样格式化文本将会是多么的繁琐!当您创建简单的 headers 和 footers(它们二者也是 HTML 5 中的新元素)时,这也可能是一个很有用的特性。看一下它们以及由 HTML 5 引入的其他一些新标记。

新语义

HTML 5 向 HTML 标记添加了许多新元素。其中一些元素将导致浏览器提供一些新的呈现处理。其他一些元素将添加一些稍后可以通过 JavaScript 变得可用的额外特性。但是,另外一些元素则不具备上述两种功能。它们与 <span>、<div> 和 <p> 看起来一样,且拥有相同的编程接口。但是,它们将添加额外的语义含义。这些新语义对于页面的非视觉用户(包括使用屏幕阅读器这样的辅助技术的用户)和搜索引擎爬虫这样的计算机程序很重要。这些新标记还向开发人员提供一些挂钩,帮助他们编写表现力更强的 CSS 选择器。图 4 展示了一个使用一些新语义元素的 Web 页面。


图 4. iPhone 上的一些新 HTML 5 元素
iPhone 上的新 HTML 5 元素 header、nav、article、section 以及 aside 的屏幕截图 

图 4 中的这个示例拥有一个 header 元素、几个 nav 元素、一个 article 元素、一个 section 元素、以及一个 aside 元素。这些元素不会导致任何特殊呈现。它们只是添加语义值,您可以使用它们来编写向它们提供视觉处理来匹配该语义值的 CSS。图 4 中显示的图片的代码如 清单 6 所示。


清单 6. HTML 5 中的新语义元素

XML/HTML Code复制内容到剪贴板
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  5.     <meta name="viewport" content="width=device-width; initial-scale=1.0;   
  6.         maximum-scale=1.0; user-scalable=0;"/>  
  7.     <meta name="apple-touch-fullscreen" content="YES" />  
  8. <title>Get the latest markup</title>  
  9. </head>  
  10. <body>  
  11.     <header style="border: 1px dotted #000;border-radius: 3px;">  
  12.         <hgroup align="center">  
  13.             <h1>Real documents have headers</h1>  
  14.             <h2>Even if they don't say so</h2>  
  15.         </hgroup>  
  16.         <hgroup>  
  17.         <nav style="-webkit-column-count:3;-webkit-column-rule: 1px solid #a00;">  
  18.             <a href="new-css.html">CSS3</a><br/>  
  19.             <a href="report.html">Canvas</a><br/>  
  20.             <a href="elements.html">Markup</a>  
  21.         </nav>  
  22.         </hgroup>  
  23.     </header>  
  24.     <article>  
  25.        <h1>There are a lot of new markup elements in HTML5</h1>  
  26.        <time datetime="2010-05-16" pubdate>Sunday, May 16</time>  
  27.        <section>Did you notice that we just had two H1's?   
  28.        But it's cool!</section>  
  29.        <aside style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" >  
  30.             If this page was really popular, I'd put an ad here and make some  
  31.             serious cash  
  32.         </aside>  
  33.     </article>  
  34. </body>  
  35. </html>  

 

您可以看到此前提到过的几个新元素。注意,您还应用了一些新的 CSS 样式来在 header 周围创建一个圆角框,并为 nav 创建几个分隔符。您还在 aside 上使用了文本溢出样式。这里的关键点是:无需额外的工作,您就可以创建更有意义的标记,然后,您可以像使用了 <div> 和 <span> 一样显示该标记。要查看拥有更多视觉和编程效果的新 HTML 5 元素的一个示例,请看 图 5。(查看图 5 的 文本版本。)


图 5. 在 iPhone 上使用 HTML 5 创建的表单
在 iPhone 上使用 HTML 5 表单元素创建的几个表单的屏幕截图 

图 5 中的屏幕使用了在 HTML 5 中可用的许多新表单元素。在很多情况下,这些元素看起来就像现有的元素,但您可以期望浏览器添加这些更丰富的表单元素的更好的视觉表示。为展示大致效果,图 6 显示了上述表单元素在 Opera 桌面浏览器中的效果。(查看图 6 的 文本版本。)


图 6. Opera 上的 HTML 5 表单元素
Opera 上使用 HTML 5 表单元素创建的几个表单的屏幕截图 

Opera 一直是实现 HTML 5 特性的先行者,这对于新的表单元素而言尤其如此。现在,看看生成 清单 4 和 清单 5 的代码,以便您更好地理解 Opera 之所以采用其呈现方式的原因。清单 7 显示了这个代码。


清单 7. 代码形式的 HTML 5 表单元素

XML/HTML Code复制内容到剪贴板
  1. <form id="settings">  
  2. <fieldset id="inputs" style="border: 1px solid #000;border-radius: 6px;">  
  3.     <legend>Settings</legend>  
  4.     <label for="name">Username</label>  
  5.     <input id="name" name="name" type="text" required autofocus /><br/>  
  6.     <label for="name">Name</label>  
  7.     <input id="name" name="name" type="text"   
  8.           placeholder="First and last name" required /><br/>  
  9.     <label for="email">Email</label>  
  10.     <input id="email" name="email" type="email"             
  11.            placeholder="example@domain.com" required /><br/>  
  12.     <label for="phone">Phone</label>  
  13.     <input id="phone" name="phone" type="tel"   
  14.           placeholder="Eg. +447500000000" required /><br/>  
  15.     <label for="dob">Date of birth</label>  
  16.     <input id="dob" name="dob" type="date" required/>  
  17.     <fieldset style="border: 1px dotted #000; border-radius: 6px">  
  18.         <legend>Preferred Contact Method</legend>  
  19.         <ol>  
  20.             <li>  
  21.                 <input id="emailMeth" name="contactMethod"   
  22.                             type="radio">  
  23.                 <label for="emailMeth">Email</label>  
  24.             </li>  
  25.             <li>  
  26.                 <input id="phoneMeth" name="contactMethod"   
  27.                             type="radio">  
  28.                 <label for="phoneMeth">Phone</label>  
  29.             </li>  
  30.         </ol>  
  31.     </fieldset>  
  32.     <label for="climate">Preferred external temperature</label>  
  33.     <input id="climate" name="climate" type="range" min="50"   
  34.           max="100" step="5" value="70"/><br/>  
  35.     <label for="color">Favorite color</label>  
  36.     <input id="color" name="color" type="color"/><br/>  
  37.     <label for="referrer">Where'd you hear about us?</label>  
  38.     <input type="url" name="refUrl" id="referrer" list="urls"/>  
  39.     <datalist id="urls">  
  40.         <option label="TechCrunch" value="http://www.techcrunch.com/">  
  41.         <option label="ReadWrite Web" value="http://www.readwriteweb.com/">  
  42.         <option label="Engadget" value="http://www.engadget.com/">  
  43.         <option label="Ajaxian" value="http://www.ajaxian.com/">  
  44.     </datalist><br/>  
  45.     <button type="button" onclick="checkInputs()">Save</button>  
  46. </fieldset>  
  47. </form>  

 

清单 7 中的 form 元素展示了 HTML 5 的许多新特性。注意两个新属性:required 和 autofocus。required 属性用于表单验证(下面将详细介绍)过程中,autofocus 属性允许选择页面上的元素以获取焦点。还要注意几个拥有 placeholder 文本的元素。这是许多网站多年来一直在使用的一个模式 — 将某个示例或解释性文本放置到一个文本框中 — 但开发人员总是必须修改(hack)该代码。图 4展示了 iPhone 如何整洁地实现这个模式。

下面,您将看到一些支持输入元素的新类型,比如 email, phone, date, range, color, 和 url。现在, 这些类型在 iPhone 和 Android 浏览器上总是呈现为文本字段,但那只是使用语义不太准确的 HTML 4.0 创建它们的样子。图 5 展示了它们未来的可能外观。date 输入在 Opera 上展示其新 UI(一个弹出式日历)前必须获得焦点。这对于 图 7 中的 url 输入也同样适用,但原因不在于它是 url 输入,而是它拥有一个 list 属性。该属性指向 datalist 元素,该元素包含该字段支持的值。当您聚焦该字段时,您将看到来自 datalist 的可能值 (本例中是几个 URL)。图 7 展示了 date 和 datalist 特性。


图 7. 带有日期和数据列表的 HTML 5 输入
带有日期和数据列表的 HTML 5 输入的屏幕截图 

随着 Webkit 持续快速发展,可以预见,许多输入类型将允许更有用的视觉表示。Opera 将为您带来更好的未来。许多这些输入字段也提供验证,HTML 5 拥有一组完整的新验证 APIs。这些特性目前还没有在 iPhone 或基于 Android 的设备上实现,但已经在它们的桌面对等设备上实现,因此,预计可以很快在移动浏览器上实现这些特性。清单 8 展示了这些新的验证 APIs 的使用情况。


清单 8. HTML 5 验证 APIs 的应用

JavaScript Code复制内容到剪贴板
  1. function checkInputs(){  
  2.     var inputs = document.getElementById("inputs").childNodes;  
  3.     var len = inputs.length;  
  4.     var i = 0;  
  5.     var input = null;  
  6.     var errors = [];  
  7.     for (i=0;i<len;i++){  
  8.         input = inputs.item(i);  
  9.         if (input.nodeName == "INPUT"){  
  10.             if (input.validity){  
  11.                 if (!input.checkValidity()){  
  12.                     errors.push(input.validationMessage);  
  13.                 }  
  14.             }  
  15.         }  
  16.     }  
  17.     var errMsg = "There are " + errors.length + " errors";  
  18.     var notify = function(){  
  19.         var notification =   
  20.             webkitNotifications.createNotification(null"Errors!", errMsg);  
  21.         notification.show();  
  22.     };  
  23.     if (window.webkitNotifications){  
  24.         if (webkitNotifications.checkPermission()){  
  25.             webkitNotifications.requestPermission(notify);  
  26.         } else {  
  27.             notify();  
  28.         }  
  29.     } else {  
  30.         alert(errMsg);  
  31.     }  
  32. }  

 

每个输入元素 拥有一个 validity 属性。可以使用这个属性,或者,也可以使用返回 ture 或 false 的 checkValidity() 函数以及validationMessage 属性来获取一条本地错误消息。在本文撰写之时,多数最新的桌面浏览器并不能为 validationMessage 返回任何一致或标准的消息,因此,它的用途有限。validity 对象可用于检查不同类型的错误,比如valueMissing、rangeOverflow、rangeUnderflow、patternMismatch 和 tooLong。例如,如果元素拥有一个必要属性而用户留空,那么 validity.valueMissing 将为 true。

最后,注意,在 清单 8 中,您在明确所有的验证错误之后,将尝试使用 webkitNotifications。这些通知与您的桌面计算机上的通知类似,可用于最新版 Chrome 中。因此,您同样可以期望它们将很快应用于 iPhone 和 Android 浏览器。API 的使用很简单明了。惟一需要注意的是,您需要检查用户是否已提供您的站点许可来使用这个 API。如果没有,您必须请求许可;反之,则传递想要被调用的函数。

结束语

在本文中,您快速浏览了 HTML 5 中许多与 UI 相关的新特性:从新元素到新样式再到绘图画布。这些特性(除了文末提到的几个例外之外)都可用于 iPhone 和基于 Android 设备上发现的基于 Webkit 的浏览器上。Blackberry 和 Nokia 智能手机等其他流行平台即将装配强大的浏览器,以便利用本文介绍的这些技术。作为一位移动 Web 开发人员,您有机会使用这些强大的视觉特性来瞄准广泛的用户,这些特性比桌面浏览器上使用 HTML、CSS 和 JavaScript 实现的任何特性都要强大。在本系列前 4 篇文章中,您了解到可用于这些精彩的新移动浏览器上的许多其他新技术(比如地理定位和 Web Workers)。移动 Web 并不是您多年来一直为之编程的 Web 的简化版,而是更强大的、拥有无限可能性的版本。

上一篇:HTML5参考手册简介 下一篇:HTML5移动应用开发第4章:Web Workers来加速您的移动

相关文章

最新文章