新型应用程序

使用 HTML5 和 JavaScript 创建 Windows 应用商店的应用

Rachel Appel

下载代码示例

Rachel Appel不仅比尔·盖茨“让每张办公桌和每个家庭都拥有一台计算机”的梦想已变为现实,而且像 Surface 平板电脑这样的设备也变得日益普及。除 Surface 平板电脑外,造型各异的新型消费设备也经历了爆炸式的增长。换言之,计算机已无所不在。

在遍布全球的这些计算机上,已安装有超过 10 亿个 Windows 操作系统;在过去两年里,每年都会售出 3 亿份 Windows 7 许可证。现有庞大的可升级 Windows 安装群与迅速增长的 Windows 8 设备(如 Surface)市场相结合,为您获得经营成功提供了一种途径。这是对 Windows 的重新构想 ― 您可以在 Windows 应用商店中发布应用,从而获得前所未有的盈利机会。

用于创建 Windows 应用商店应用的平台、语言和工具集

为了创建 Windows 应用商店的应用,您需要有 Windows 8、Visual Studio 2012 以及任何可满足您的应用要求的 SDK,如 Windows Live SDK 或 Bing Maps SDK。由于这种系统安装和配置的要求极低,使得 Windows 8 上的应用开发(从安装到部署)变得十分容易。

安装必备软件之后,下一步是选择语言。如果您是有 Microsoft 堆栈开发背景的 Microsoft .NET Framework 开发人员,使用 C# 或 Visual Basic 编写过 Windows 窗体、Windows Presentation Foundation (WPF) 或 Silverlight 应用,那么使用 XAML 和 C# 或 Visual Basic 创建 Windows 应用商店应用就变得轻而易举。C++ 开发人员还可以将 C++ 作为编译语言,同时以 XAML 作为伴随的 GUI。

如果您是 Web 开发人员(包括 ASP.NET),那么您可以将开放标准 HTML5、JavaScript 和 CSS3 方面的现有知识直接付诸 Windows 应用商店应用的开发。Web 开发人员可以继续使用许多常用的第三方 JavaScript 库,如 jQuery 或 Knockout。在本文中,我选择使用 JavaScript 语言。

无论您有怎样的开发背景,开发本机 Windows 8 应用的进入门槛都不高。这是因为,Windows 运行时 (WinRT) 作为一个平台包含了 Windows 核心服务上部的 API,如图 1 所示。

Architecture of Windows Store Apps
图 1 Windows 应用商店应用的体系结构

通过 WinRT API,您可以访问 Windows 8 提供的所有功能,包括硬件 API,如内置网络摄像头、地理位置、光线传感器和加速感应器等硬件。当然,您还可以轻而易举地获得基本平台功能(如内存管理、身份验证、全球化和异步处理)以及 Windows 应用商店的应用功能(如搜索、共享和通信)。甚至还有用于操作音频和视频的 API;不过,如果您要编写 JavaScript 应用,则 HTML5 <audio> 和 <video> 元素效果甚佳。您可在 bit.ly/ZCwcJE 的“Windows 应用商店应用 API 参考”页上浏览完整 API。

Windows 应用商店应用的原则

Windows 应用商店应用在运行中应提供完全沉浸式全屏体验,为用户交付流畅的内容,而应用本身及其命令不会对用户产生阻碍。Windows 应用商店的应用以清晰简明的形式显示数据,将用户的注意力集中在内容上。

Windows 应用商店的应用可完成传统 Windows 或 Web 应用以前无法实现的工作,例如,利用 Windows 运行时中称为“合约”的元素作为各应用间的联络途径,以方便而统一的方式共享、搜索和相互通信。

出色的用户体验是 Windows 应用商店应用开发的关键要素,这包括从呈现和布局,直至导航和应用性能等诸多方面体验。用户期望各应用之间以及应用与操作系统之间表现出一致性。Windows 应用商店的应用全部以用户体验为中心,通过遵循一定的设计原则(如采用一致的字体、Windows UI 轮廓以及可伸缩的网格系统)增强用户使用应用时的舒适程度。这种一致性贯穿于各个应用以及 Windows 8 本身。

确保触控功能以及鼠标输入操作的可靠性和一致性十分重要,因为用户现在可通过更多方式与计算设备进行交互,比如鼠标、触控笔、触摸屏、摄像头和传感器等。

由于含处理器(如 ARM)的电池供电设备正逐渐成为计算设备的主流,Windows 8 必须对总内存和每个应用的内存进行严格管理,以便在资源不足的情况下也能提供快速流畅的体验。Windows 8 应用具有简单直接的过程生命周期,以确保提供最佳体验。

虽然许多应用都可作为 Windows 应用商店应用运行,但并非每个应用都是好的备选应用。例如,Visual Studio 本身蕴含着许多现代 UI 设计原则,但它的用途是让用户执行命令(换言之,进行编程)。因此,它不十分适合作为 Windows 应用商店应用。

Visual Studio 2012 Windows 应用商店应用项目模板

Visual Studio 2012 推出了一套新模板,帮助采用 C#、Visual Basic、C++ 和 JavaScript 开发 Windows 应用商店应用。无论使用何种语言,都可采用以下模板样式:

  • 空白: 一个骨架模板,其中含有构建 Windows 应用商店应用所需的最少文件。
  • 网格: 显示有一个网格的模板,该网格使用 Windows 8 UI 轮廓以及用于实现多种功能的模板代码,包括导航和贴靠视图支持(后文有详细说明)。 
  • 拆分: 在一个双列视图中显示项目和项目详细信息列表的模板,便于用户在各项目之间快速切换。
  • 固定: 在 default.html 页中使用 ViewBox 对象的一个空白模板。ViewBox 就是在游戏中使用的 WinRT 对象。
  • 导航: 带有“空白”项目结构的模板,另外在“/home”目录下包含导航以及一组基本应用资源(即 home.html、home.js 和 home.css)。

由于“网格”模板包含展示许多出色 Windows 8 功能(如贴靠视图、屏幕缩放和导航支持)的代码,因此该模板是编写 Windows 应用商店应用的理想入门方法。

在新建 JavaScript“网格”项目模板后,通过检查结构,可发现该项目包含全面的标准 Web 文件类型(如 .html、.css 和 .js 文件),这些文件都组织在该项目根目录下的文件夹中。随后,通过按 F5 或从“调试”菜单中选择“启动调试”,可调试并运行 Windows 应用商店应用。

在 Windows 应用商店应用模板中,default.html 是 Windows 应用商店应用的起始页,它附带一个脚本文件 /js/default.js,其中含有基本过程生命周期管理代码。与其他所有 HTML 文件一样,default.html 包含您可能需要的代码,包括脚本引用以及用于定义页面结构的新 HTML5 语义标记。以下代码片段位于 default.html <body> 标记内,它使用 WinJS 控件实现导航并加载 groupedItems.html 页:

<div id="contenthost"
  data-win-control="Application.PageControlNavigator"
  data-win-options=
  "{home: '/pages/groupedItems/groupedItems.html'}"></div>

data-* 属性是 HTML5 中用于向 HTML 元素应用自定义代码或行为的方式。在 Windows 应用商店应用开发中,data-win-* 属性通常引用 Windows JavaScript 控件。 Windows JavaScript 控件是内置的 WinRT 组件,可应用于 HTML 元素以增强或修改其行为或样式。 Data-win-* 属性在 Windows 应用商店的 JavaScript 应用中普遍采用,尤其在进行数据绑定时。

Windows 应用商店应用中的数据访问

“网格”模板在“/js”文件夹中有一个名为“data.js”的文件,其中包含用于生成数组数据集的代码,还有用于对数据进行分组和操作的函数。 data.js 文件还包含一些示例数据,您可将之替换为自己的数据。 在本文中,我将使用一个倒计时应用的数据,该应用显示某个事件(如节假日)之前剩余的天数。

在 data.js 文件中,可在文件开头附近找到唯一的“// TODO”注释。 请用您自己的代码替换该注释下面的代码,使该代码如同以下代码段所示,此代码段通过 XMLHttpRequest 调用检索 JSON 数据,然后创建数据集,包括动态属性(如 daysToGo)和消息字段:

var list = new WinJS.Binding.List();
...
WinJS.xhr({ url: "data.json" }).then(function (xhr) {
  var items = JSON.parse(xhr.responseText);          
  items.forEach(function (item) {
    item.daysToGo = Math.floor(
      (Date.parse(item.eventDate) - new Date()) / 86400000);
    item.message = item.daysToGo + " days until " + item.title;
    if (item.daysToGo >= 0) {
      list.push(item);
    };
  })
})

data.js 的第一行代码实例化一个简单命名为“list”的 WinJS.Binding.List 对象,此首行代码将各个项推送到此 List 之中。

该 List 对象实现 JSON 数据或 JavaScript 数组与 HTML 元素之间的绑定。 此列表变量填充数据后,请在 HTML 标记中使用绑定表达式将 List 成员绑定至 HTML 元素。

在通过调用 JSON.parse 读取 JSON 数据时,名称/值对中的名称在运行时与 JavaScript 对象的属性进行匹配。 以下 JSON 数据显示 JSON 结构如何映射到前面代码段中项目变量的成员。 key、title、eventDate、image、color 和 group 字段都映射到该项目对象的属性:

[{"key":"1","group":{"key":"group1","title":"Important Dates"},
"title":"Rachel's Birthday","eventDate":"01/13/2013",
"image":"/images/birthday.png","color":"#6666FF"},
{"key":"2","group":{"key":"group1","title":"Important Dates"},
"title":"Ada Lovelace Day","eventDate":"10/16/2013",
"image":"/images/ada.jpg","color":"#fff"},
{"key":"3","group":{"key":"group2","title":"Holidays"},"title":"Christmas",
"eventDate":"12/25/2013","image":"/­images/­tree.png","color":"#ef0d0d"},
{"key":"4","group":{"key":"group3","title":"School"},"title":"School Ends","eventDate":"6/10/2013","image":"/images/schoolbus.png","color":"#fff"},
{"key":"5","group":{"key":"group2","title":"Holidays"},"title":"Thanksgiving",
"eventDate":"11/29/2012","image":"/­images/­thanksgiving.png","color":"#FFCC00"},
{"key":"6","group":{"key":"group2","title":"Holidays"},"title":"New Year's Day", "eventDate":"1/1/2013","image":"/images/celebrate.png","color":"#f8baba"}]

至此已加载数据,接着您需要确保 List 对象绑定至正确的 HTML 元素。 图 2 中对“/pages/groupedItems/groupedItems.html”页的修改显示了进行中的数据绑定。

图 2 使用 WinJS 控件将 List 对象数据绑定至 HTML 元素

<!-- These templates are used to display each
  item in the ListView declared below.
-->
<div class="headertemplate" data-win-control="WinJS.Binding.Template">
  <button class="group-header win-type-x-large win-type-interactive"
    data-win-bind="groupKey: key"
    onclick="Application.
navigator.pageControl.
navigateToGroup(
      event.srcElement.groupKey)"
      role="link" tabindex="-1" type="button">
    <span class="group-title win-type-ellipsis"
      data-win-bind="textContent: title"></span>
    <span class="group-chevron"></span>
  </button>
</div>
<div class="itemtemplate" data-win-control="WinJS.Binding.Template" >
  <div id="myitem" class="item"
    data-win-bind="style.background: color">
    <img class="item-image" src="#"
      data-win-bind="src: image; alt: title" />
    <div class="item-overlay">
    <h2 class="item-title" data-win-bind="innerText: message"></h2>
      <h6 class="item-subtitle"
        data-win-bind="textContent: eventDate"></h6>
    </div>
  </div>
</div>
<!-- The content that will be loaded and displayed.
-->
<div class="fragment groupeditemspage">
  <header aria-label="Header content" role="banner">
    <button class="win-backbutton" aria-label="Back"
       disabled type="button"></button>
    <h1 class="titlearea win-type-ellipsis">
      <span class="pagetitle">How long until...</span>
    </h1>
  </header>
    <section aria-label="Main content" role="main">
      <div id="listView" class="groupeditemslist"
        aria-label="List of groups"
        data-win-control="WinJS.UI.ListView"
        data-win-options="{  selectionMode: 'multi',
        tapBehavior:'toggleSelect' }"></div>
    </section>
</div>

图 2 中每个含有 data-win-bind 属性的 HTML 元素都有一个绑定表达式,该表达式与前面代码段中项目变量的属性名称相匹配,因此,您只需确保绑定表达式与字段名称匹配。 还务必记得修改 groupedDetail.html 和 itemDetails.html 页中的绑定表达式,以便在用户浏览到这些页面时显示正确的数据。

在 Windows 模拟器中运行该项目会产生类似图 3 所示的结果。 (您可到 bit.ly/M1nWOY 了解有关使用该模拟器的更多内容。)

Replace the Sample Data to Make a Basic App
图 3 替换示例数据以创建基本应用

可以看到,您只需简单地替换 Visual Studio 模板中的代码便可实现快速的数据访问。 但是,项目通常会很大或很复杂,从而使维护变得困难。 如果是这样,请使用 Model-View-ViewModel (MVVM) 模式简化维护工作。 网上对这种模式有极为详细的记载。

您的应用此时已经可以运行,但您应利用 Windows 8 的众多出色功能让您的应用从众多应用中脱颖而出。

打造您的 Windows 应用商店应用品牌

考虑到 Windows 8 的焦点在于起始页,因此可顺理成章从起始页开始打造品牌。 起始页中有很多动态磁贴,这些磁贴不仅仅是一堆方形图标。 它们是向用户展示您的应用和吸引用户的最佳方式。 动态磁贴之所以称为“动态”,是因为可以在这些磁贴中动态显示信息和图像,为您的应用增添吸引力。

Windows 应用商店应用需要三个单独的磁贴图像,分别具有以下像素大小:

  • 徽标: 150 x 150(标准磁贴)
  • 宽徽标: 150 x 310(宽磁贴)
  • 小徽标: 30 x 30(仅显示在应用商店的应用列表中)

这些图像可以采用任何常用图像格式,具有透明背景的图像效果最佳。 从项目根目录打开 package.appxmanifest 文件会显示配置调色板,可在其中选择磁贴图像并设置背景颜色。 图 4 演示了标准磁贴和宽磁贴。

Countdown App Standard and Wide Tiles
图 4 倒计时应用标准磁贴和宽磁贴

设置磁贴时是配置初始屏幕的好时机,只需选择一个图像和背景颜色即可完成配置,而不必编写代码。 虽然磁贴和初始屏幕是打造您的应用品牌的重要因素,但您还可以通过更多方法打造您的应用品牌并装饰您的应用,您可在 bit.ly/M4HYmL 了解这方面的信息。

您的应用的 Windows 8“必备”功能

您的应用此时或许已能正常运行,但您可以发掘 Windows 8 应用生态系统中的许多新功能和 API,让您的应用真正超凡脱俗。 我将逐一做简短介绍。

应用栏 应用栏 (AppBar) 是每个应用的必备功能,它是 default.html 中的一个 WinJS 控件。 应用栏通常是不可见的,但在用户右键单击或将鼠标光标从屏幕的顶部或底部扫过时,应用栏就会横跨屏幕底部显示出来。 图 5 显示了含有三个按钮及其相应事件侦听器的应用栏的标记。

图 5 带有用于添加、删除和导出数据的按钮的应用栏

// AppBar markup in default.html
<div id="appbar" data-win-control="WinJS.UI.AppBar">
  <button data-win-control="WinJS.UI.AppBarCommand"
    data-win-options="{id:'addItem', label:'Add',
    icon:'add', section:'global'}" type="button"></button>
  <button data-win-control="WinJS.UI.AppBarCommand"
    data-win-options="{id:'exportData', label:'Save',
    icon:'save', section:'global'}" type="button"></button>
  <button data-win-control="WinJS.UI.AppBarCommand"
    data-win-options="{id:'deleteItem', label:'Delete',
    icon:'delete', section:'selection'}" type="button"></button>
</div>
// Script in groupedItems.js
document.getElementById("exportData").addEventListener("click", Data.exportData);
document.getElementById("addItem").addEventListener("click", this.addItem);
document.getElementById("deleteItem").addEventListener("click", this.deleteItem);

全局应用栏命令应放于应用栏的右侧,上下文命令则放于左侧。 可使用 CSS 设置应用栏样式,因为这里只有一个 <div>。

贴靠视图 Windows 应用商店的应用可以全屏运行,也可在一种称为“贴靠视图”的模式下运行,当用户将应用“粘在”屏幕的左侧或右侧时即会进入这种模式。 由于该应用现有屏幕资源较少,因此只显示必要的数据较好。

“网格”模板中内置贴靠视图支持,因此,您需要确认贴靠后数据显示良好,可以呈现相关且可读的信息。 应用栏在应用贴靠时也会正常工作,因此可能还需要进行样式调整。

语义缩放 Windows 8 中这个有利于触控的新功能可用于在一个易于理解的视图中聚合大量数据。 用户可通过以下方式调用语义缩放功能:

  • 触控: 缩小手势
  • 鼠标: Ctrl+滚轮
  • 键盘: Ctrl - 和 Ctrl +

语义缩放不是简单地显示数据的缩放视图,更多地是以一种利于导航的有意义方式来显示数据。 如果有大量数据,用户最好进行总览显示,而不是在大量信息中滚动显示。 请考虑如何以最有意义的方式呈现数据。

搜索和共享 在应用之间搜索和共享数据是新型应用的核心要素。 用户现在可以一次跨多个应用进行搜索,然后共享找到的数据。 或者,您的应用可将自身注册为共享目标,并接受用户从其他 Windows 应用商店应用共享的数据。 应用间的通信从未像现在这样简单而一致。

选取器控件 这些控件是已针对现代用户界面进行过更新的传统 Windows 控件(如“文件打开选取器”或“文件保存选取器”),或是一直作为许多版本 Windows 应用的主流界面的打印设置对话框。

媒体 由于使用 JavaScript 生成的 Windows 应用商店应用全面支持 HTML5,因此,<audio> 和 <video> 元素的工作方式与它们在普通网页中的工作方式相同。 

Toast 通知 Toast 通知是向用户提供瞬时消息的一种方法,而无论该应用是否正在使用中。 Toast 通知的最常见形式是电子邮件提醒弹出窗口和手机短信。 Toast 消息可以包含文本和图像,可作为吸引用户使用您的应用的另一种方法。 您可以将相同的通知发布到 Windows 8 锁屏以快速浏览任何待读消息。

新一代应用

总之,Windows 8 是重新构想的 Windows 操作系统,在一个史无前例的市场上引入了该操作系统自 Windows 95 以来一些最重大的改变。 通过内置的 Visual Studio 项目模板,您可以在这个最大的应用创作市场上,比以往更加方便和快速地发布能够盈利的应用。

因篇幅所限,本文无法讨论您在 Windows 应用商店应用中可以而且应该使用的所有了不起的功能,因此,我强烈建议您查看“新一代应用”计划 (bit.ly/W8GenAppDev)。 该计划可指导您完成在 30 天内构建 Windows 应用商店(或 Windows Phone)应用的过程,提供了免费的技术和设计咨询及帮助以及独有的提示与资源。

Rachel Appel 是 Microsoft 在纽约市的开发推广人员。 您可以通过 rachelappel.com 网站与她联系,或者通过电子邮件 (rachel.appel@microsoft.com) 与她联系。 您还可以在 Twitter 上(网址为 twitter.com/rachelappel)留意她的最新更新。

衷心感谢以下技术专家对本文的审阅: Ian LeGrow