怎么使用JavaScript和HTML创建博客阅读器
这篇文章主要讲解了“怎么使用JavaScript和HTML创建博客阅读器”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用JavaScript和HTML创建博客阅读器”吧!
十多年的路北网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都营销网站建设的优势是能够根据用户设备显示端的尺寸不同,自动调整路北建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联公司从事“路北网站设计”,“路北网站推广”以来,每个客户项目都认真落实执行。
在 Visual Studio 中创建新项目
为我们的应用创建一个名为 WindowsBlogReader
的新项目。以下是操作方法:
启动 Visual Studio。
在“起始页”选项卡中,单击“新建项目”。随即将打开“新建项目”对话框。
在“已安装”窗格中,展开 JavaScript并选择“Windows 应用商店应用”模板类型。JavaScript 可用的项目模板随即将显示在对话框的中心窗格中。
在中心窗格中,选择“拆分应用”项目模板。
在“名称”文本框中,输入 "WindowsBlogReader"。
单击“确定”以创建项目。这需要花费一点时间。
下面是在解决方案资源管理器中显示的项目的结构。页面文件夹包含两组文件,一组文件用于项页面,另一组文件用于拆分页面。这些组中的每个组为 PageControl、一组 HTML、CSS 以及 JavaScript 文件,这些文件定义应用可以导航至或用作自定义控件的页面。
新项目包含创建项 PageControl和拆分 PageControl所需的 HTML、CSS 和 JavaScript 文件。稍后我们将为项详细信息 PageControl添加文件。
启动我们的新 Windows 应用商店应用
如果你非常想看到基本的分隔应用的外观,请按 F5 以生成、部署并启动应用。应用显示为全屏页面,标题为 "WindowsBlogReader",包含一列示例项目,显示为网格。每个项目表示一组数据。点击或单击列表中的项目以导航至拆分页。拆分页包含两个 核心内容区域。在左侧,你可以看到与所选组关联的项目列表。在右侧,可以看到所选项目的内容。可以通过点击或单击页面上的“后退”按钮来返回项目页。
运行应用时,应用会提取 items.html 中的(或其中链接的)HTML、CSS 和 JavaScript,并将其注入到作为应用起始页的 default.html 页面中。对于在应用容器中运行的代码默认可以执行的操作有一些限制。例如,你的应用不能访问 Internet 或摄像头,除非你声明应用需要此访问权限,且用户在安装应用时授予了此访问权限。如需了解详细信息,请打开 package.appxmanifest,并转至“许可范围”选项卡。
更改标题和背景色
我们来执行两个简单的任务来自定义应用。
若要更改应用标题,请打开 items.html,然后将 itemspage
中的 h2元素文本替换为 "Windows 团队博客",如此处所示。
Windows Team Blogs
若要设置应用的背景色,请打开 default.css,并将此 background-color属性添加到 #contenthost
中。
#contenthost { height: 100%; width: 100%; background-color: #0A2562; }
按 F5 来生成、部署并启动此应用。请注意,项目页的标题已更改,项目页和拆分页的背景色为蓝色。
Note项目中的 images 文件夹包含默认的文件,系统将这些文件用于应用启动时应用的磁贴和初始屏幕。在本教程中,我们不更改这些内容,但是你可以按照自己的喜好使用其他图像。只 需将要使用的图像文件添加到 images 文件夹中即可。打开 package.appxmanifest,将“应用程序 UI”选项卡上“徽标”、“小徽标”和“初始屏幕”的内容替换为你的图像文件的路径。
替换示例数据
项目模板包含运行应用时看到的示例数据。我们使用这些步骤为 Windows 团队博客将这些示例数据替换为来自 ATOM 源的数据:
删除示例数据
打开 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 对象,以存储来自源的内容。JSON 对象是名称/值对的未经排序的容器。例如,博客标题存储在一个 JSON 对象中,该对象名为 title,还有一个从 ATOM 源检索的值。使用 JSON 对象使我们将来自源的内容绑定到应用的控件变得很简单。
// Create an object for each feed in the blogs array blogs = [ { key: "blog1", url: 'http://blogs.windows.com/skydrive/b/skydrive/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog2", url: 'http://blogs.windows.com/windows/b/windowsexperience/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog3", url: 'http://blogs.windows.com/windows/b/extremewindows/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog4", url: 'http://blogs.windows.com/windows/b/business/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog5", url: 'http://blogs.windows.com/windows/b/bloggingwindows/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog6", url: 'http://blogs.windows.com/windows/b/windowssecurity/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog7", url: 'http://blogs.windows.com/windows/b/springboard/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog8", url: 'http://blogs.windows.com/windows/b/windowshomeserver/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog9", url: 'http://blogs.windows.com/windows_live/b/developer/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog10", url: 'http://blogs.windows.com/ie/b/ie/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog11", url: 'http://blogs.windows.com/windows_phone/b/wpdev/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog12", url: 'http://blogs.windows.com/windows_phone/b/wmdev/atom.aspx', title: 'tbd', updated: 'tbd', acquireSyndication: acquireSyndication, dataPromise: null }];
检索源数据
对于此部分中的步骤,我们使用适用于 JavaScript 的 Windows 库来管理联合源。
将此代码添加到 acquireSyndication
函数。我们调用 Windows.JS.xhr函数以检索源内容。此调用为异步调用。幸运的是,程序已经为我们处理好了在进行异步调用时可能会遇到的许多复杂问题。xhr返回时,我们将收到结果的承诺,此承诺将返回到调用方。
// 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函数,等待所有承诺均已满足后,再从 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 源数据。首先,我们使用 responseXML属性以获得响应正文,然后使用 querySelector方法以及所需的选择器来获得博客的标题和最后更新日期。我们使用 Windows.Globalization.DateTimeFormatting.DateTimeFormatter来转换显示的上次更新日期。
如果 articlesResponse.responseXML
是 null,则说明加载博客时出错,因此我们会在博客发布位置显示一条错误消息。
// 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; if (articleSyndication) { // 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); } else { // There was an error loading the blog. feed.title = "Error loading blog"; feed.updated = "Error"; blogPosts.push({ group: feed, key: "Error loading blog", title: feed.url, author: "Unknown", month: "?", day: "?", year: "?", content: "Unable to load the blog at " + feed.url }); } }); }); }); 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 }); }
使数据可用
现在,我们已完成了将源数据存储到数组中的代码,我们需要按照 ListView控件的预期来对源数据进行分组。我们还需要完成将源数据绑定到 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
数组中反映内容。