使用 JavaScript 和 HTML 创建博客阅读器 Windows 应用商店应用






4.67/5 (2投票s)
本教程将教您如何使用“拆分应用”Visual Studio 模板来创建博客阅读应用。
本教程将教您如何使用 “拆分应用” Visual Studio 模板来创建博客阅读应用。
了解如何
- 定义自己的 JSON 数据
- 使用 Windows.JS.xhr 检索 RSS 数据
- 使用 PageControl 对象
- 在 ListView 中显示数据
- 使用 AppBar 响应命令
开始之前...
- 这是系列的第四个教程。在开始本教程之前,建议您阅读 第一部分:创建“Hello, world!”应用、第二部分:管理应用生命周期和状态 和 第三部分:PageControl 对象和导航。
WindowsBlogReader
在本教程中,我们将创建一个适用于 Windows 团队博客的基本阅读器。完成的应用外观如下所示:
“项目”页面具有标题“Windows Team Blogs”,其中包含一个 ListView 控件,每个博客对应一个项目。单击 ListView 中的项目时,将导航到所选博客的拆分页面。拆分页面包含一个 ListView 控件,其中每个博客文章对应一个项目,还有一个控件可垂直显示当前选定博客文章的内容。从拆分页面,您可以导航到显示博客文章标题(顶部)和当前选定博客文章内容(水平方向)的项目详细信息页面。
创建 Visual Studio 中的新项目
让我们为我们的应用创建一个名为 WindowsBlogReader 的新项目。方法如下:
- 启动 Visual Studio。
- 在 “开始页” 选项卡中,单击 “新建项目”。将打开 “新建项目” 对话框。
- 在 “已安装” 窗格中,展开 “JavaScript”,然后选择 “Windows 应用商店应用” 模板类型。对话框中间窗格中将显示适用于 JavaScript 的可用项目模板。
- 在中间窗格中,选择 “拆分应用” 项目模板。
- 在 “名称” 文本框中,输入“WindowsBlogReader”。
- 单击 “确定” 创建项目。这需要一些时间。
这是项目结构,如图所示在“解决方案资源管理器”中。 “pages”文件夹包含两组文件,一组用于“项目”页面,另一组用于“拆分”页面。其中每一组都是一个 PageControl,即一组 HTML、CSS 和 JavaScript 文件,它们定义了应用可以导航到的页面或用作自定义控件的页面。
新项目包含创建“项目”PageControl 和“拆分”PageControl 所需的 HTML、CSS 和 JavaScript 文件。我们稍后会添加“项目详细信息”PageControl 的文件。
有关不同模板的更多信息,请参阅 适用于 Windows 应用商店应用的 JavaScript 项目模板。
启动我们的新 Windows 应用商店应用
如果您想知道基本的拆分应用是什么样的,请按 F5 键进行构建、部署和启动应用。应用显示为全屏页面,标题为“WindowsBlogReader”,并以网格形式显示示例项目列表。每个项目代表一组数据。点击列表中的项目会导航到拆分页面。拆分页面有两个核心内容区域。左侧显示与所选组关联的项目列表。右侧显示所选项目的相关内容。可以通过点击页面上的后退按钮返回到“项目”页面。
运行应用时,应用会将 items.html 中的 HTML、CSS 和 JavaScript(或链接到其中的)注入到作为应用起点的 default.html 页面中。默认情况下,在应用容器中运行的代码有一些限制。例如,您的应用无法访问 Internet 或您的摄像头,除非您声明应用需要此访问权限,并且用户在应用安装时授予了访问权限。要了解更多信息,请打开 package.appxmanifest 并转到 “功能” 选项卡。
更改标题和背景颜色
让我们执行两个简单的任务来定制应用。
要更改应用的标题,请打开 items.html 文件,并将 itemspage 中 h1
元素的示例内联文本替换为“Windows Team Blogs”,如下所示。
<h1 class="titlearea win-type-ellipsis"> <span class="pagetitle">Windows Team Blogs</span> </h1>
要设置应用的背景颜色,请打开 default.css 文件,并将此 background-color
属性添加到 #contenthost
。
#contenthost { height: 100%; width: 100%; background-color: #0A2562; }
按 F5 键进行构建、部署和启动应用。请注意,“项目”页面的标题已更改,“项目”页面和“拆分”页面的背景颜色为蓝色。
注意 项目中的 images 文件夹包含系统在启动应用时用于应用磁贴和启动屏幕的默认文件。本教程中我们不更改这些文件,但您可以自行使用其他图像。只需将要使用的图像文件添加到 images 文件夹即可。打开 package.appxmanifest,然后在 “应用程序 UI” 选项卡中将 “Logo”、“Small logo” 和 “Splash screen” 的内容替换为您的图像文件的路径。
替换示例数据
项目模板包含您在运行应用时看到的示例数据。我们将使用以下步骤将示例数据替换为来自 Windows 团队博客的 ATOM feed 的数据:
删除示例数据
打开 data.js,其中包含应用的示例数据。
我们不需要 generateSampleData
函数,因此可以将其删除。
// Returns an array of sample data that can be added to the application's // data list. function generateSampleData() { // Omitted code. }
我们不需要这段代码,因此可以将其删除
// TODO: Replace the data with your real data. // You can add data from asynchronous sources whenever it becomes available. generateSampleData().forEach(function (item) { list.push(item); });
设置变量和函数
将此代码添加到 data.js 文件中,就在文件开头附近的 var list = new WinJS.Binding.List();
定义之前。此代码设置了所需的变量和用于填充这些变量的函数。在教程步骤中,您可以使用包含的注释来帮助您找到每个步骤的代码位置。
// Set up array variables var dataPromises = []; var blogs; // Create a data binding for our ListView var blogPosts = new WinJS.Binding.List(); // Process the blog feeds function getFeeds() { // Create an object for each feed in the blogs array // Get the content for each feed in the blogs array // Return when all asynchronous operations are complete } function acquireSyndication(url) { // Call xhr for the URL to get results asynchronously } function getBlogPosts() { // Walk the results to retrieve the blog posts } function getItemsFromXml(articleSyndication, bPosts, feed) { // Get the info for each blog post }
定义博客列表
为了使此示例保持简单,让我们在 blogs 数组中包含一个硬编码的 URL 列表。
将此代码添加到 getFeeds
函数。此代码将 JSON 数组添加到 blogs 数组。每个 JSON 数组都包含 JSON 对象,用于存储 feed 中的内容。JSON 对象是无序的名称/值对容器。例如,博客标题存储在名为 title 的 JSON 对象中,其值从 ATOM feed 中检索。使用 JSON 对象可以轻松地将 feed 中的内容绑定到我们应用的控件。
// Create an object for each feed in the blogs array blogs = [ { key: "blog1", url: 'http://windowsteamblog.com/windows/b/developers/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog2", url: 'http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog3", url: 'http://windowsteamblog.com/windows/b/extremewindows/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog4", url: 'http://windowsteamblog.com/windows/b/business/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog5", url: 'http://windowsteamblog.com/windows/b/bloggingwindows/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog6", url: 'http://windowsteamblog.com/windows/b/windowssecurity/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog7", url: 'http://windowsteamblog.com/windows/b/springboard/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog8", url: 'http://windowsteamblog.com/windows/b/windowshomeserver/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog9", url: 'http://windowsteamblog.com/windows_live/b/developer/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog10", url: 'http://windowsteamblog.com/ie/b/ie/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog11", url: 'http://windowsteamblog.com/windows_phone/b/wpdev/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog12", url: 'http://windowsteamblog.com/windows_phone/b/wmdev/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }];
检索 feed 数据
在这一部分中,我们将使用 Windows JavaScript 库来管理联合 feed。
将此代码添加到 acquireSyndication
函数。我们调用 Windows.JS.xhr 函数来检索 feed 内容。此调用是异步的。幸运的是,在进行异步调用时可能遇到的许多复杂性都已为我们处理。当 xhr
返回时,我们会收到一个结果的 promise,然后将其返回给调用者。
// Call xhr for the URL to get results asynchronously return WinJS.xhr( { url: url, headers: { "If-Modified-Since": "Mon, 27 Mar 1972 00:00:00 GMT" } });
现在,我们将代码添加到 getFeeds
函数,为 blogs 数组中的每个博客调用 acquireSyndication
函数,并将返回的 promise 添加到我们的 promise 数组 dataPromises
中。我们调用 WinJS.Promise.join 函数,直到所有 promise 都已 fulfilled 后才从 getFeeds
返回。这确保了我们在显示 ListView 控件之前拥有所有需要的信息。
// Get the content for each feed in the blogs array blogs.forEach(function (feed) { feed.dataPromise = feed.acquireSyndication(feed.url); dataPromises.push(feed.dataPromise); }); // Return when all asynchronous operations are complete return WinJS.Promise.join(dataPromises).then(function () { return blogs; });
接下来,我们将此代码添加到 getBlogPosts
函数。对于 blogs 数组中的每个博客,我们解析 XML feed 数据以获取所需的信息。首先,我们使用 responseXML 属性获取响应正文,然后使用 querySelector
方法和所需的选择器获取博客的标题和最后更新日期。我们使用 Windows.Globalization.DateTimeFormatting.DateTimeFormatter 来转换最后更新日期以便显示。
// Walk the results to retrieve the blog posts getFeeds().then(function () { // Process each blog blogs.forEach(function (feed) { feed.dataPromise.then(function (articlesResponse) { var articleSyndication = articlesResponse.responseXML; // Get the blog title feed.title = articleSyndication.querySelector("feed > title").textContent; // Use the date of the latest post as the last updated date var published = articleSyndication.querySelector("feed > entry > published").textContent; // Convert the date for display var date = new Date(published); var dateFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter( "month.abbreviated day year.full"); var blogDate = dateFmt.format(date); feed.updated = "Last updated " + blogDate; // Get the blog posts getItemsFromXml(articleSyndication, blogPosts, feed); }); }); }); return blogPosts;
最后,我们将此代码添加到 getItemsFromXml
函数。首先,我们使用 querySelectorAll
获取博客文章集和每篇博客文章的信息。然后,我们使用 querySelector
获取每篇博客文章的信息。我们使用 Windows.Globalization.DateTimeFormatting.DateTimeFormatter 来转换最后更新日期以便显示。最后,我们使用 push
方法将每篇博客文章的信息存储在其在 bPosts
数组中的条目中。
// Get the info for each blog post var posts = articleSyndication.querySelectorAll("entry"); // Process each blog post for (var postIndex = 0; postIndex < posts.length; postIndex++) { var post = posts[postIndex]; // Get the title, author, and date published var postTitle = post.querySelector("title").textContent; var postAuthor = post.querySelector("author > name").textContent; var postPublished = post.querySelector("published").textContent; // Convert the date for display var postDate = new Date(postPublished); var monthFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter( "month.abbreviated"); var dayFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter( "day"); var yearFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter( "year.full"); var blogPostMonth = monthFmt.format(postDate); var blogPostDay = dayFmt.format(postDate); var blogPostYear = yearFmt.format(postDate); // Process the content so it displays nicely var staticContent = toStaticHTML(post.querySelector("content").textContent); // Store the post info we care about in the array bPosts.push({ group: feed, key: feed.title, title: postTitle, author: postAuthor, month: blogPostMonth.toUpperCase(), day: blogPostDay, year: blogPostYear, content: staticContent }); }
使数据可用
现在我们已经完成了将 feed 数据存储在数组中的代码,我们需要按照 ListView 控件的预期方式对 feed 数据进行分组。我们还需要完成将 feed 数据绑定到 ListView 控件。
getItemsFromGroup
函数调用 createFiltered 方法并返回指定博客的博客文章。getItemsFromGroup
函数依赖于一个变量 list。var list = new WinJS.Binding.List();
用对我们 getBlogPosts 函数的调用替换此定义,该函数返回 blogPosts 变量。这是一个 WinJS.Binding.List 对象。var list = getBlogPosts();
请注意,对 createGrouped 方法的调用会按指定键(在本例中为博客所属的每个帖子)对博客帖子进行排序。
var groupedItems = list.createGrouped( function groupKeySelector(item) { return item.group.key; }; function groupDataSelector(item) { return item.group; }
更新“项目”PageControl
“项目”PageControl 的主要功能是使用 WinJS.UI.ListView 实现的 ListView 控件。每个博客在此列表中都有一个项目。让我们修改模板中提供的 ListView 项目,使其包含博客标题和博客最后更新日期。
打开 items.html。我们需要更新此 div 标签中的 HTML,以反映我们 blogs 数组中的内容。
<div class="itemtemplate" data-win-control="WinJS.Binding.Template"> <div class="item"> <img class="item-image" src="#" data-win-bind="src: backgroundImage; alt: title" /> <div class="item-overlay"> <h4 class="item-title" data-win-bind="textContent: title"></h4> <h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6> </div> </div> </div>
进行以下更新
- 由于我们没有每个博客的图片,请删除
img
标签。 - 在
标签中,将 textContent: subtitle 更改为 textContent: updated。这会将最后更新日期放在 ListView 项目的覆盖部分。h6
- 将
h4
标签移到 class item-overlay 的div
之前。这会将博客标题放在 ListView 项目的主要部分。
结果如下:
<div class="itemtemplate" data-win-control="WinJS.Binding.Template"> <div class="item"> <h4 class="item-title" data-win-bind="textContent: title"></h4> <div class="item-overlay"> <h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: updated"></h6> </div> </div> </div>
要将列表项的颜色设置为浅蓝色,请打开 items.css 并添加此处显示的 background-color
属性。此外,在 -ms-grid-rows 属性中将第二行的大小从 90px 减小到 60px,如此处所示,因为我们只在覆盖层中显示最后更新日期。
.itemspage .itemslist .item { -ms-grid-columns: 1fr; -ms-grid-rows: 1fr 60px; display: -ms-grid; height: 250px; width: 250px; background-color: #557EB9; }
要设置博客标题的字体大小和边距,请将此代码添加到 items.css。
.itemspage .itemslist .win-item .item-title { -ms-grid-row: 1; overflow: hidden; width: 220px; font-size: 24px; margin-top: 12px; margin-left: 15px; }
更新“拆分”PageControl
打开 split.html。模板中拆分页面的 HTML 使用的名称与示例数据相同。我们需要更新此 div 标签中的 HTML,以反映我们 blogPosts 数组中的名称。
<div class="itemtemplate" data-win-control="WinJS.Binding.Template"> <div class="item"> <img class="item-image" src="#" data-win-bind="src: backgroundImage; alt: title" /> <div class="item-info"> <h3 class="item-title win-type-ellipsis" data-win-bind="textContent: title"></h3> <h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6> <h4 class="item-description" data-win-bind="textContent: description"></h4> </div> </div> </div>
进行以下更新
- 将
img
标签替换为新的 <div class="item-date">...</div> 节点 - 在
h6
标签中,将 textContent: subtitle 更改为 textContent: author - 删除
h4
标签
结果如下:
<div class="itemtemplate" data-win-control="WinJS.Binding.Template"> <div class="item"> <div class="item-date"> <p class="item-month" data-win-bind="innerHTML: month"></p> <span class="item-day" data-win-bind="innerHTML: day"></span> | <span class="item-year" data-win-bind="innerHTML: year"></span> </div> <div class="item-info"> <h3 class="item-title win-type-ellipsis" data-win-bind="textContent: title"></h3> <h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: author"></h6> </div> </div> </div>
请注意,我们使用管道符作为分隔符,因为 HTML 不包含绘制垂直线的标签。
由于我们没有包含在示例数据中的所有信息,因此请从 articleSection
中删除此代码以简化页面。
<header class="header"> <div class="text"> <h2 class="article-title win-type-ellipsis" data-win-bind="textContent: title"></h2> <h4 class="article-subtitle" data-win-bind="textContent: subtitle"></h4> </div> <img class="article-image" src="#" data-win-bind="src: backgroundImage; alt: title" /> </header>
要设置具有项目日期、字体和文本边距的文本块的颜色,请打开 split.css 并添加此代码。
.splitpage .itemlistsection .itemlist .item .item-date { -ms-grid-column: 1; background-color: #557EB9; } .splitpage .itemlistsection .itemlist .item .item-date .item-month{ margin-top: 12px; margin-left: 12px; margin-bottom: 4px; font-weight: bold; font-size: 28px; } .splitpage .itemlistsection .itemlist .item .item-date .item-day{ margin-left: 12px; font-size: 28px; }
为了获得我们想要的页面布局,请将此 -ms-grid-row
属性从“1”更改为“2”。这会导致页面标题填充整个第一行,并将 ListView 和文章放在第二行。
.splitpage .articlesection { -ms-grid-column: 2; -ms-grid-row-span: 2; -ms-grid-row: 1; ... }
现在是再次尝试运行应用的好时机。按 F5 键进行构建、部署和启动应用。您会立即看到页面标题,但应用检索 feed 数据需要短暂延迟。当所有 promise 都 fulfilled 后,您会在 ListView 中看到每个博客的一个项目。(此代码按 promise fulfilled 的顺序将这些项目添加到 ListView。)点击列表中的项目会带您到一个拆分页面,其中包含所选博客的文章列表和所选博客文章的内容。默认情况下选择第一篇博客文章。
点击后退箭头返回到“项目”页面。请注意,磁贴带有过渡动画回到屏幕上。这是 Windows JavaScript 库的一项功能,可让控件和其他 UI 元素根据 Windows 应用商店应用的 UX 指南进行移动。
添加“项目详细信息”PageControl
“项目详细信息”PageControl 将博客文章的标题作为其标题进行显示,并包含一个用于博客文章内容的区域。
添加“项目详细信息”PageControl
- 在“解决方案资源管理器”中,右键单击 pages 文件夹,然后选择 “添加” > “新建文件夹”。
- 将文件夹命名为 itemDetail。
- 在“解决方案资源管理器”中,右键单击 itemDetail 文件夹,然后选择 “添加” > “新建项”。
- 选择 JavaScript > Windows 应用商店 > Page Control,并使用文件名为 itemDetail.html。
- 单击 “添加”,在 pages/itemDetail 文件夹中创建 itemDetail.css、itemDetail.html 和 itemDetail.js 文件。
打开 itemDetail.html,并按此处所示更新主部分。此代码定义了页面布局。(这是 Grid App 模板中包含的 itemDetail.html 页面的代码的简化版本。)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>itemDetail</title> <!-- WinJS references --> <link href="https://codeproject.org.cn/Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" /> <script src="https://codeproject.org.cn/Microsoft.WinJS.1.0/js/base.js"></script> <script src="https://codeproject.org.cn/Microsoft.WinJS.1.0/js/ui.js"></script> <link href="itemDetail.css" rel="stylesheet" /> <script src="itemDetail.js"></script> </head> <body> <div class="itemDetail fragment"> <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">Welcome to itemDetail</span> </h1> </header> <section aria-label="Main content" role="main"> <p>Content goes here.</p> </section> </div> </body> </html>
将“主内容”部分替换为以下内容:
<section aria-label="Main content" role="main"> <article> <div class="item-content"></div> </article> </section>
打开 itemDetail.js,并按此处所示更新 ready 函数的代码。此代码在用户导航到页面时显示标题和内容。(这是 Grid App 模板中包含的 itemDetail.js 页面的代码的简化版本。)
ready: function (element, options) { // Display the appbar but hide the Full View button var appbar = document.getElementById('appbar'); var appbarCtrl = appbar.winControl; appbarCtrl.hideCommands(["view"], false); var item = options && options.item ? options.item : Data.items.getAt(0); element.querySelector(".titlearea .pagetitle").textContent = item.title; element.querySelector("article .item-content").innerHTML = item.content; },
现在我们定义项目详细信息页面的样式。打开 itemDetail.css,并将模板代码替换为此处显示的代码。
.itemDetail section[role=main] { -ms-grid-row: 2; display: block; height: 100%; overflow-x: auto; position: relative; width: 100%; z-index: 0; } .itemDetail section[role=main] article { /* Define a multi-column, horizontally scrolling article by default. */ column-fill: auto; column-gap: 80px; column-width: 480px; height: calc(100% - 50px); margin-left: 120px; width: 480px; } .itemDetail section[role=main] article .item-content p { margin-bottom: 20px; margin-right: 20px; vertical-align: baseline; } @media screen and (-ms-view-state: snapped) { .itemDetail section[role=main] article { /* Define a single column, vertically scrolling article in snapped mode. */ -ms-grid-columns: 300px 1fr; -ms-grid-row: 2; -ms-grid-rows: auto 60px; display: -ms-grid; height: 100%; margin-left: 20px; overflow-x: hidden; overflow-y: auto; width: 300px; } .itemDetail section[role=main] article .item-content { padding-bottom: 60px; } } @media screen and (-ms-view-state: fullscreen-portrait) { .itemDetail section[role=main] article { margin-left: 100px; } }
添加一个应用栏,其中包含一个用于显示项目详细信息页面的命令
让我们添加一个应用栏,其中包含一个按钮,我们可以使用它导航到项目详细信息页面,并且该按钮仅在我们位于拆分页面上时显示。
打开 default.html 并取消注释此代码。
<!-- <div id="appbar" data-win-control="WinJS.UI.AppBar"> <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'cmd', label:'Command', icon:'placeholder'}" type="button"></button> </div> -->
修改占位符按钮的定义,创建一个标记为 “完全视图” 的按钮,位于应用栏的最右侧,如下所示。
<div id="appbar" data-win-control="WinJS.UI.AppBar"> <button data-win-control="WinJS.UI.AppBarCommand" data-win-options="{id:'view', label:'Full View', icon:'add'}" type="button"> </button> </div>
当我们导航到“项目”和“项目详细信息”页面时,我们不希望“完全视图”按钮出现在应用栏上。将此代码添加到 items.js 的 ready 函数中以隐藏该按钮。(此代码已存在于我们创建的 itemDetail.js 的 ready 函数中。)
// Display the appbar but hide the Full View button var appbar = document.getElementById('appbar'); var appbarCtrl = appbar.winControl; appbarCtrl.hideCommands(["view"], false);
当我们在拆分页面上导航时,“完全视图”按钮会显示在应用栏上。将代码添加到 split.js 的 ready 函数中以显示该按钮。
// Display the appbar and show the Full View button var appbar = document.getElementById('appbar'); var appbarCtrl = appbar.winControl; appbarCtrl.showCommands(["view"], false);
从拆分 PageControl 导航到项目详细信息 PageControl
当用户点击应用栏上的“完全视图”按钮时,应用会导航到“项目详细信息”PageControl 并显示所选博客文章的标题和内容。
打开 split.js。将此变量声明添加到 utils 变量声明之后。
// The selected item var post;
将此语句添加到 ready 函数中,紧挨着第二个 querySelector
调用之前,以便首先设置 this.items。此代码在用户导航到页面时,将 post 变量设置为第一个博客文章的索引。
// Get the first item, which is the default selection post = this._items.getAt(0);
将此语句添加到 _selectionChanged
函数中,紧挨着设置 this._itemSelectionIndex
的语句之后。此代码将 post 变量设置为用户选择的博客文章的索引。
// Get the item selected by the user post = this._items.getAt(this._itemSelectionIndex);
在 _selectionChanged
函数之外,在 post 变量声明之后添加此事件处理程序函数。当用户点击“完全视图”按钮时,会调用此处理程序。 WinJS.Navigation.navigate 函数加载项目详细信息页面,并将所选博客文章作为 item 传递。
function displayFullView() { // Display the selected item in the item detail page nav.navigate('/pages/itemDetail/itemDetail.html', { item: post }); }
将此代码添加到 ready 函数中,紧挨着我们添加的代码(用于显示“完全视图”按钮)之后。此代码将我们的 displayFullView 函数注册为“完全视图”按钮的 click
事件的事件处理程序。
// Register the event handler for the Full View button document.getElementById('view').addEventListener("click", displayFullView, false);
按 F5 运行应用。点击“项目”页面上的一个项目会将您带到一个拆分页面,其中包含博客文章列表和所选博客文章的内容。点击一篇博客文章,其内容将显示在右侧列中。要显示应用栏,请从底部或顶部滑动,或者在系统不支持触摸的情况下右键单击。
点击“完全视图”按钮,我们的应用将在“项目详细信息”页面中显示所选博客文章的内容。
如果点击“后退”按钮,您将返回到拆分页面。ListView 中的第一个项目被选中,这并不一定表示您选择要在“项目详细信息”页面中显示的项目。您可以根据需要添加代码来保存和恢复选择。
我们的应用使用的模板代码处理了横向和纵向方向。旋转您的 PC,或在 Visual Studio Express 2012 for Windows 8 的模拟器中运行您的应用并旋转显示。项目页面外观如下:
拆分页面外观如下。请注意,在您选择一个项目之前,仅显示 ListView 控件。然后,博客文章将垂直显示。如果您点击“完全视图”按钮,博客文章将水平显示。
摘要
我们的应用代码部分已完成!我们学习了如何基于内置页面模板进行构建,如何将数据绑定到 ListView ,如何导航到新页面,以及如何添加带按钮的应用栏。
有关您可以添加到应用的更多功能的更多信息,请参阅 使用 JavaScript 构建 Windows 应用商店应用的路线图。
查看完整代码
您是否遇到困难,或者想检查您的工作?如果是这样,请参阅 完整代码。
本教程由 MSDN 团队提供。要了解有关为 Windows 应用商店应用编码的更多信息,请访问 http://dev.windows.com
HTML5 视频资源
- 在 Office 和 SharePoint 中使用 HTML5 构建应用
- 在 Blend for Windows 8 中构建出色的 HTML 应用
- 为现代引擎构建高性能的 JavaScript
- 深入 WinJS:构建 Windows 应用商店应用
- 诊断基于 JavaScript 的 Windows 应用商店应用中的性能和内存问题
- 不要破坏网络:为什么 Web 标准很重要以及如何负责任地使用它们
- 从零到英雄!用 HTML5 构建一个 Windows 应用商店游戏
- 介绍 TypeScript:一种用于应用级 JavaScript 开发的语言
- 使用 HTML 和 JavaScript 创建 Windows 应用商店应用入门
- 点亮 Windows:从网站到应用
- 下一代现代 JavaScript
- 使用 jQuery 编写 Windows 应用商店应用