使用 HTML5 和 Ajax 开发数据驱动的交互式应用程序

HTML5 是大量新兴 web 技术的通用术语,这些技术包括标准化的富媒体和交互性。HTML5 也可作为开发强大的离线应用程序的基础。对于经验丰富的 web 开发人员来说,使用 HTML5 比利用 Objective-C 或 Java™ 语言更具吸引力,但是 HTML5 应用程序拥有其自己的学习曲线。本文描述如何成功混合在线内容,同时为未联网的用户提供丰富的体验。

样例应用程序

本样例应用程序旨在用于各种桌面和移动设备。它提供餐饮食谱集。三个食谱是静态的,可供用户离线时使用。在线时,应用程序将能够显示 “当日食谱”,该食谱由一个通过 Ajax 交付内容的 web 服务提供。

技术重用是敏捷的 web 开发的关键。该样例应用程序使用两个流行的开源库:

  • jQuery — 对 JavaScript 和 DOM 可靠的跨平台访问
  • jQTouch — 使用 WebKit 浏览器的 HTML5 移动应用程序框架

参阅 参考资料,了解有关 jQuery 和 jQTouch 的更多信息。

尽管使用 Google Chrome 也可以,但为了获得最佳结果,最好使用 Apple Safari V4 或更高版本开发 HTML5 应用程序。

使用 jQTouch

您可以将 jQTouch 应用程序作为单一 HTML 文档对其进行最佳管理。应用程序中的每一 “页” 都是一个含有惟一 id 属性的不同的 HTML <div>。jQTouch 应用程序的基本轮廓如下所示:

  1. HTML 头和导入
  2. <div> 开头
  3. 没有或有更多带有惟一 ID 的页面 <div>

设置导入

样例应用程序的顶部导入应用程序的 CSS 和 JavaScript。它还配置 HTML5 离线缓存。清单 1 提供必要的代码。

清单 1. jQTouch 和 HTML5 离线应用所需的头部代码

<!DOCTYPE html>
<html manifest="sample.manifest">
  <head>
    <meta charset="utf-8" />
    <title>Sample recipe application</title>
    <style type="text/css">@import "jqtouch/jqtouch/jqtouch.min.css";</style>
    <style type="text/css">@import "jqtouch/themes/jqt/theme.min.css";</style>
    <style type="text/css">@import "sample.css";</style>
    <script src="jqtouch/jqtouch/jquery.1.3.2.min.js" 
            type="text/javascript"></script>
    <script src="jqtouch/jqtouch/jqtouch.min.js" 
            type="text/javascript"></script>
    <script src="sample.js" type="text/javascript"></script>
  </head>

启用 HTML5

关于 HTML5 标记

简化的 DOCTYPE 对于熟悉 DTDs 和 XML 的程序员来说很陌生:其惟一目的在于在 web 浏览器中触发 “标准模式”。由于浏览器从不使用基于 DTD 的验证(由于 “标签汤(tag soup)” HTML 的激增),因此提供严格的 DOCTYPE 并无特别的好处。如果使用 XML 感知的工具构建 Web 应用程序,您仍然可以使用 HTML V4.01 或 XHTML V1.0 DOCTYPE,但由于 HTML5 扩展的原因,该文件将不能完全验证。

类似地,<meta charset="utf-8"> 可能看起来很陌生,但它也是有效的 HTML5。参阅 参考资料,探究 HTML5 中简化的语法。

该样例应用程序具有在离线时仍然可访问的功能。包含 manifest 属性就可实现该功能。该属性的值必须是到缓存清单文件的路径,如下所示。

<html manifest="sample.manifest">

缓存清单通常包含两组资源:

  • 离线缓存所需的资源列表
  • 仅在文档在线时可用的资源列表

缓存清单的语法相当简单,如清单 2 所示。

清单 2. 样例应用程序的缓存清单文件

CACHE MANIFEST

# This is a comment and will be ignored 

# Files specific to this application:
sample.js
sample.css

# Files that are a part of jQTouch:
# (See the sample code for a complete list)
jqtouch/jqtouch/jqtouch.min.css

NETWORK:
# These resources will be available only when online:
sample.json

第一行总是 CACHE MANIFEST。可能处于脱机状态的每种资源 — HTML 页面、CSS、JavaScript、图像或任何其他文件 — 被列在一个新行上。首次访问应用程序时,浏览器检查缓存清单、下载所有资源并存储它们以供脱机时使用。

NETWORK: 一行后面的资源不缓存,且仅在联网时可访问。尽管这里列出了一个文件,您可以使用部分路径名。例如,您可以在这里包含 /online/ 并设置应用程序,使所有仅供在线使用的资源位于该路径下。

如果忘记将应用程序中的所有资源列为离线或在线,通常会导致整个应用程序未被标记为离线启用。当前实现中可能造成混乱的其他细微之处包括:

  • web 服务器必须将清单文件作为 text/cache-manifest 类型予以服务。
  • 指向缓存清单的文件(在本例中是 sample.html)无需列出。
  • 清单中列出的项目仅在修改清单本身 时被重新载入,而不是在这些资源变更时载入。
  • web 服务器应当在不带缓存响应头的情况下为清单文件提供服务。
  • 如果 web 页面引用一个未列入清单的文件,应用程序可能不会缓存,因而就不能脱机使用。该错误通常是静默的。在 Safari V4 和更高版本中,检查 Activity 面板,看是否有任何警告。

如果一个 HTML5 离线应用程序经过合理设置,就可以一次使用一个浏览器和服务器访问该应用程序,然后关闭服务器或本地网路访问,点击刷新之后应当仍然能够与内容交互。如果浏览器指出,站点无法访问,重新检查以上列表,看是否有配置问题。


使用 jQTouch 进行开发

jQTouch 库需要几个导入:

  • jqtouch.min.css. — jQTouch 自身的 CSS
  • theme.min.css. — 当前主题的 CSS(本例使用默认主题)
  • jquery.1.3.2.min.js or later — jQuery 本身
  • jqtouch.min.js. — jQTouch 主脚本
  • samples.js. — 自定义 JavaScript,定义该方法的特有功能

移动 web 性能提示

根据一般的 web 最佳实践,将 JavaScript 导入脚本放在 HTML 文档的底部,紧接在 <body> 标记闭合之前。为清晰起见,本例将其放在 <head> 中。

由于无线连接缓慢,移动设备具有高 HTTP 事务性开销,因此建议您将多个 JavaScript 文件整合到一个库中。这通过一个自动化构建/部署实现;使用小的、定义明确的、离散的库可易于人工开发工作。

类似地,在多个图像处考虑使用 CSS sprites。另外,将样式表分解为单一文档来进行部署。

jQTouch 内容页面

jQTouch 应用程序中的每个页面实际上都是一个遵循以下约定的 HTML <div>

  • 它必须拥有惟一的 id 属性。
  • 必须使用普通的 HTML 锚元素在应用程序某处链接 ID。
  • jQTouch 应用程序的主页是含有 value current 类的 <div>

jQTouch 库提供大量方法来激活页到页之间的过渡。默认情况下,它使用精美的 “swipe” 过渡,该过渡使用 CSS3。在许多 WebKit 实现中,这些过渡是硬件加速的,提供一种自然应用程序似的感觉。您可以在 jQTouch 应用程序的主页上找到与这些页面的链接,如清单 3 所示。

清单 3. “current” 类指定的主页

<div id="home" class="current">
      <div class="toolbar">
        <h1>HTML5 Sample</h1>
      </div>
      <ul class="rounded">
        <li class="arrow"><a href="#recipe1">Breakfast Circles</a></li>
        <li class="arrow"><a href="#recipe2">Slowhand Jackson</a></li>
        <li class="arrow"><a href="#recipe3">Potato Chip Cookies</a></li>
        <li class="arrow online-required"><a href="#recipe4">Recipe of the Day</a></li>
      </ul>
    </div>

大多数 jQTouch 页面包含一个含惟一 ID 的外部 <div>,紧接着是一个 <div>,其 toolbar 属性包含页面标题。随后的内容都是以列表或附加段落的形式出现。

roundedarrow 类均在主 jQTouch 样式中定义。根据所安装的主题,其外观可能有所不同。本例使用默认的黑色和灰色主题,如图 1 所示。

图1.样例应用程序的主页

前三个食谱都是在同一 HTML5 页面中定义的静态内容。它们都有惟一的 IDs — 例如,recipe1。这些 IDs 用于从主页上指定新页面,如下所示:

<a href="#recipe1">Breakfast Circles</a></li>

清单 4 包含第一个食谱的源代码。图 2 展示了 HTML 页面呈现。

清单 4. jQTouch 应用程序中的静态内容

<div id="recipe1" class="recipe">
      <div class="toolbar">
        <h1>Breakfast Circles</h1>
        <a class="back" href="#">Back</a>
      </div>
      <ul class="rounded">
        <li>2C flour</li>
        <li>1/2C sugar</li>
        <li>1/2C confectioners sugar</li>
        <li>2T Earl Grey tea leaves (about 6 bags)</li>
        <li>1/2t salt</li>
        <li>1t vanilla</li>
        <li>1/2C butter</li>
        <li>Cold water</li>
      </ul>
      <p>
      Pulse dry ingredients in food processor to pulverize tea leaves. 
      Add vanilla, butter and pulse, adding as little water as 
      necessary to form loose dough. Divide into two 2" logs and roll 
      with parchment paper. Chill 30 min.</p>
      <p>
        Cut into 1/4"-thick wafers and bake at 375 degrees on parchment 
        until edges start to brown, about 12 min.
      </p>
    </div>

注意,<div> 包含一个新的类值:recipe。默认的 jQTouch 样式表不对嵌套的 <p> 元素提供好的样式控制,该元素在这里用作食谱说明。由于 jQTouch 仅仅是一个 Web 应用程序,您可以使用普通 CSS 随意定制样式。

在本例中,sample.css 包含一些简单的定制项,包括 div.recipe p { margin: 1em; },以为食谱说明提供一个美观的页边距。

图2.样例应用程序的主页

三个静态食谱均可供离线用户使用,因为其内容包含在 HTML 页面内。本文下一部分展示如何混合在线和离线内容来创建一个灵活、可扩展的 Web 应用程序,从而提供良好的脱机功能。


上线

列表中的最后一个食谱项目,如清单 5 所示,包含一个额外的 HTML 类:online-required

清单 5. 仅在用户在线时显示的项目

<li class="arrow online-required">
  <a href="#recipe4">Recipe of the Day</a>
</li>

在本应用程序的 CSS 定制层中,.online-required 被设置为 display: none。这意味着,在默认情况下将应用程序看作是离线的,不显示在线网络资源。

那么应用程序如何知道您何时在线?相关代码在 JavaScript 定制脚本 sample.js 中,如清单 6 所示。

清单 6. 用于管理在线网络资源的 JavaScript

/* Initialize jQTouch on startup. 
 [ See sample code for complete listing ] */

// Standard jQuery method to run code when the browser 
// has finished loading all resources
jQuery(document).ready(function () {
  
  // If online, show all online-only resources
  if (window.navigator.onLine) {
    jQuery('.online-required').show();
  }
  ...

HTML5 指定一个 JavaScript API 值 window.navigator.onLine。当该值为真时,浏览器在线且与网络相连。离线时,它只能访问缓存清单中的离线资源。在该应用中,当应用程序在线时,所有含 online-required 类的 DOM 元素都会显示。

测试 window.navigator.onLine

在不支持 HTML5 的桌面 Web 浏览器中,window.navigator.onLine 的值总是 true,即使计算机不联网。您需要引入一个测试框架来模拟脱机状态,或仅使用一个移动设备执行测试。

接受在线数据

使用在线数据填充 jQTouch 应用程序的一个有效方法是,预先提供框架页来保留该数据。清单 7 显示了仅供在线使用的食谱的 <div>

清单 7. 仅供在线使用的食谱的占位符 jQTouch 页面

<div id="recipe4" class="recipe">
  <div class="toolbar">
    <h1>Recipe of the Day</h1>
    <a class="back" href="#">Back</a>
  </div>
  <!-- The recipe will be populated here -->
</div>

现在,在定制的 JavaScript 中,您需要一个事件处理程序来请求食谱并用结果填充 HTML 页面。最明显的方法是为 #recipe4 ID 定义一个 onclick 处理程序。

但是,jQTouch 推翻了常规的点击行为来完成页到页的神奇过渡。而您可以利用 CSS3 会触发开始和结束事件这样一个事实。您可以使用 jQuery 绑定到这些事件,即使事件并非 jQuery 原生的。下面就是绑定代码:

jQuery('#recipe4').bind('pageAnimationStart', function () {
  ...
});

未看到滑动过渡或 Ajax 加载?

在撰写本文时,只有 Safari 版本 4 和 5 以及 Mobile Safari 显示视觉过渡且触发 pageAnimationStart 事件。如果您需要支持其他 WebKit 浏览器,请使用不同的事件。

pageAnimationStart 事件几乎在点击事件之后立即触发。过渡完成时,pageAnimationEnd 触发。我喜欢将大部分动作与开始事件联系起来,因为这就为浏览器留出一些时间来收集数据,同时用户可以观看动画。

通过 Ajax 填充数据

剩下的工作就是一些正常的 Ajax 交互。本例假定最终数据为 JSON 格式。在本例中,数据直接来源于一个 JSON 文件 — sample.json,如清单 8 所示。

清单 8. 包含当日食谱的 JSON 数据

[ { "title" : "Doggie Delight", "ingredients" :  \
["1 cup dry kibble", "1 pound butter",  "1 beef bouillon cube", \
"2 tbsp oregano" ], "instructions": "Combine all ingredients in bowl.\
 Season to taste. Serve immediately." }]

清单 9 包含接受该数据并填充 <div> 占位符的代码。

清单 9. 用于填充占位符的 JSON 数据

jQuery.ajax({ url: "sample.json",
  success: function (data) {

    // Set the recipe title
    jQuery('#recipe4 h1').text(data[0].title);


    // Create a UL and add each recipe item to it
    var ul = jQuery('<ul class="rounded">');
    jQuery.each(data[0].ingredients, function (index, item) {
      jQuery('<li>').text(item).appendTo(ul);
    });

    // Add the ingredients list and the recipe instructions
    jQuery('#recipe4').append(ul).append(
      jQuery('<p>').text(data[0].instructions));

图 3 显示动态数据的最终显示结果。

图3.浏览器中的动态食谱


结束语

每天有更多的新移动设备进入市场。我们可以为每个新平台和硬件开发定制的本机应用程序,而小型敏捷团队也有机会使用类似的性能特征创建跨平台的移动 web 应用程序。无论是作为大型本机应用程序的原型还是一流站点本身,移动 web 应用程序对于已经熟知 HTML、JavaScript 和 CSS 的开发人员来说很有吸引力。

HTML5 中可用的 JavaScript APIs 表明,web 应用程序能比以往访问更多硬件数据 — 不仅是网络状态,还有方向、位置和其他特性。在很多情况下,这些 APIs 已经在流行的移动浏览器中受到广泛支持。

Web 开发人员不应感到落后于人而急于开发移动应用程序。您可能已经具备了开发智能手机、上网本和平板机所应有的技能。


下载

样例脚本os-html5data-app-code-samples.zip4KBHTTP

关于下载方法的信息

本文转载于developerWorks,原文在这里

相关推荐