几个月前,谷歌发布了一项类似 Twitter 的新服务,名为 Buzz。我们可以使用此服务在任何网站上显示我们的最新动态。因此,在本教程中,我将指导您完成构建自己的 Buzz 小部件的过程。
目前,没有可与 Buzz 服务配合使用的 API; Google 预计将在未来几个月内提供一个更新,但目前公开更新以 Atom 源的形式提供。
首先,我们需要从 Buzz 服务获取数据。为此,我们将设置一个 PHP 脚本来从 Buzz 服务读取数据。该脚本将是一种代理,我们将使用它来检索数据。通过这样做,我们可以发出 AJAX 请求,并获取包含所需更新的 XML 文档。
这是最初的 PHP 代码:
header('Content-type: application/xml'); //Setting up the response content type to XML $handle = fopen($_GET['url'], "r"); //Open the given URL if ($handle) { while (!feof($handle)) { $buffer = fgets($handle, 4096); //reading the data echo $buffer; } fclose($handle); }
将此文件另存为“readfeed.php”,并记住这只是一个示例。在现实世界的项目中,您应该清理 url 参数,并确保用户没有打开文件系统上的重要内容。
一旦我们可以读取这些数据,我们就需要构建一个对象来保存 JavaScript 代码。创建一个新文件并将其命名为“buzz-widget.js”。要扩展一个对象,我们需要使用“prototype”属性;如果您对此有疑问,您应该观看教程,其中 Jeffrey 向我们展示了它如何与本机对象一起使用。
我们的对象的结构将是这样的:
var BuzzReader = function(options){ //Step 1 //code for the constructor }; BuzzReader.prototype = { //Step 2 renderTo: "", proxy : "readfeed.php", user : "", url : "", items : 10, onLoad : function(){}, onRender: function(){}, render : function(element){ }, read : function(){ }, parse : function(xml,success,response){ }, format : function(date){ }, createDate : function(str){ } };
在第一步中,我们为对象创建了构造函数。现在,我们将检查所需的配置,并从我们的代理读取更新。
让我们研究小部件的构造函数。
var BuzzReader = function(options){ var url = "http://buzz.googleapis.com/feeds/{user}/public/posted"; //Step 1 jQuery.extend(this,options || {}); //Step 2 if(this.user === "") throw "The 'user' property is required"; //Step 3 if(this.renderTo === "") throw "The 'renderTo' property is required"; if(this.url === "")this.url = url.replace(/{user}/g,this.user); //Step 4 this.read(); //Step 5 };
在第一步中,我们定义了要从中检索数据的 Buzz 服务的 URL。我们将用用户配置替换“{user}”字符串(请参阅步骤 4)。
在第二步中,我们使用给定的选项覆盖了默认属性;我们使用 jQuery.extend 来做到这一点。
在第三步中,我们检查了所需的配置,其中之一是“user”和“renderTo”。如果缺少其中之一,我们将抛出异常。这对于使用我们插件的开发人员来说非常有用。
在第四步中,我们在变量“url”中搜索“{user}”字符串,并将其替换为我们希望在小部件中显示其动态更新的用户。
最后一步非常重要。在这里,我们开始读取和显示信息的过程。
我们已经设置了 PHP 脚本,用于将数据提取到我们的服务器。现在,我们只需要发出 Ajax 请求即可使用 jQuery 检索数据;让我们看一下下面的代码:
read : function(){ this.el = jQuery(this.renderTo); //Step 1 this.loader = this.el.append("<div class=\"buzz-loading\"></div>"); jQuery.ajax({ //Step 2 url : this.proxy, data : "url="+this.url, context : this, success : this.parse }); },
在第一步中,我们将一个新元素附加到容器中,通知查看者我们当前正在处理信息。
在第二步中,我们发出了 Ajax 请求。最重要的是“上下文”属性;此配置将允许您更改服务器响应时调用的函数的上下文。最后,我们将上下文设置为“this”,即 BuzzReader 对象。
请记住,PHP 脚本需要“url”参数。所以不要忘记发送;当服务器响应时,执行“parse”方法。
Buzz 服务以 Atom feed 格式提供数据,因此我们需要解析并提取我们需要的信息。
这是从 Buzz 服务返回的 XML 文档的示例:
<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:media="http://search.yahoo.com/mrss" xmlns:activity="http://activitystrea.ms/spec/1.0/"> <link rel="self" type="application/atom+xml" href="http://buzz.googleapis.com/feeds/117377434815709898403/public/posted"/> <link rel="hub" href="http://pubsubhubbub.appspot.com/"/> <title type="text">Google Buzz</title> <updated>2009-12-14T20:04:39.977Z</updated> <id>tag:google.com,2009:buzz-feed/public/posted/117377434815709898403</id> <generator>Google - Google Buzz</generator> <entry> <title type="html">Buzz by A. Googler from Mobile</title> <published>2009-12-14T20:04:39.000Z</published> <updated>2009-12-14T20:04:39.977Z</updated> <id>tag:google.com,2009:buzz/z12bx5v5hljywtfug23wtrrpklnhf3gd3</id> <link rel="alternate" type="text/html" href="http://www.google.com/buzz/117377434815709898403/DmuNZHSfZ7t/buzz-buzz"/> <author> <name>A. Googler</name> <uri>http://www.google.com/profiles/a.googler</uri> </author> <content type="html">Bzz! Bzz!</content> <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb> <activity:object> <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type> <id>webupdates:a.googler@gmail.com.1258ecae5db</id> <title>Buzz by A. Googler from Mobile</title> <content type="html">Bzz! Bzz!</content> </activity:object> <link rel="replies" type="application/atom+xml" href="http://buzz.googleapis.com/feeds/117377434815709898403/comments/z12bx5v5hljywtfug23wtrrpklnhf3gd3" thr:count="0"/> <thr:total>0</thr:total> </entry> </feed>
一旦我们知道响应,我们就可以使用 jQuery 轻松解析文档。
parse : function(xml,status){ var that = this; var nodes = jQuery("entry",xml); //Step 1 this.el.empty(); var info = []; nodes.each(function(){ //Step 2 var date = that.createDate(jQuery("published",this).text()); info.push({ title : jQuery("title",this).text(), author : jQuery("author > name",this).text(), uri : jQuery("author > uri",this).text(), summary : jQuery("summary ").text(), content : jQuery("content:first",this).text(), published : that.format(date), updated : jQuery("updated",this).text(), date : date, reply : jQuery("link[rel=replies]",this).attr("href") }); }); this.data = info; //Step 3 this.onLoad.call(this,info); this.render(this.renderTo); //Step 4 },
我们收到两个参数:第一个是数据,在本例中是 XML 文档;第二个参数是请求的文本状态。
在第一步中,我们获得了所有“入口”节点;这是我们的 Buzz 更新和我们需要的所有信息所在的地方。接下来,我们清空小部件的容器,并创建一个空数组来将数据存储为每个节点的 JavaScript 对象。
在第二步中,我们迭代“entry”节点并提取“标题”、“作者”、“内容”等。这是一个非常简单的过程;我们所要做的就是编写选择器并设置搜索的根,在本例中根是节点“entry”。
我想指出我们提取“reply”属性的行 - 选择器看起来像这样:
link[rel=replies]
我们指定需要节点“link”,该节点的属性“rel”等于“replies”。这很重要,因为每个“条目”内都有许多“链接”节点。
在第三步中,我们创建了对包含数据的数组的“this.data”引用。之后,我们执行“onLoad”事件并传递我们提取的信息。
在第四步中,我们执行了 render 方法。
在继续“render”方法之前,让我们回顾一下“createData”和“format”方法。我们为每个条目调用这些方法。
在“createDate”方法中,我们只会使用给定的字符串创建一个新的 Date 对象。该字符串的格式为“2009-12-14T20:04:39.977Z”,因此我们可以按如下方式创建 Date 对象:
createDate : function(str){ var date = new Date(); date.setDate(str.substring(8,10)); date.setMonth(str.substring(5,7) - 1); date.setFullYear(str.substring(0,4)); date.setUTCHours(str.substring(11,13)); date.setUTCMinutes(str.substring(14,16)); date.setUTCSeconds(str.substring(17,19)); return date; }
或者我们可以使用一个简单的正则表达式来格式化字符串并将其提供给 Date 构造函数:
createDate : function(str){ //str = '2009-12-14T20:04:39.977Z' str = str.substring(0,19).replace(/[ZT]/," ").replace(/\-/g,"/"); //str = '2009/12/14 20:04:39' return new Date(str); }
在 format 方法中,我们将使用刚刚创建的日期对象,并返回发布日期和系统本地时间之间的时间 - 例如“11 分钟前”或“3 小时前”。
format : function(date){ var diff = (((new Date()).getTime() - date.getTime()) / 1000), days = Math.floor(diff / 86400), months = Math.floor(days / 31); if (isNaN(days) || days < 0)return date.toString(); if(days == 0){ if(diff < 60)return "Just now"; if(diff < 120)return "1 minute ago"; if(diff < 3600)return Math.floor( diff / 60 ) + " minutes ago"; if(diff < 7200)return "1 hour ago"; if(diff < 86400)return Math.floor( diff / 3600 ) + " hours ago"; }else if(days < 31){ if(days == 1)return "Yesterday"; if(days < 7)return days + " days ago"; if(days < 31)return Math.ceil( days / 7 ) + " weeks ago"; }else{ if(months == 1)return "A month ago"; if(months < 12)return Math.ceil( days / 31 ) + " months ago"; if(months >=12)return Math.floor( days / 365 ) + " years ago"; } },
前面的代码虽然有点乏味,但非常简单。首先,我们获得当前时间与发布日期之间的差异(以分钟、天和月为单位)。之后,我们简单地比较了结果,并返回了一个正确格式的字符串。
现在让我们回顾一下“渲染”方法。
到目前为止,我们仅从 Buzz 服务器中提取了数据,并解析了 XML 文档。这意味着我们已准备好在屏幕上显示信息。
render : function(element){ this.onRender.call(this,this); //Step 1 var html = []; //Step 2 html.push("<ul>"); for(var i = 0; i < this.items || i < this.data.lenght;i++){ html.push("<li><strong><a href=\""+this.data[i].uri+"\">"+this.data[i].author+"</a></strong><span>"+this.data[i].published+"</span>"+this.data[i].content+"</li>"); } html.push("</ul>"); this.el.append(html.join("")); //Step 3 },
在第一步中,我们触发了“onRender”事件,这对于使用我们插件的程序员来说再次很有用。
在第二步中,我们创建了一个数组来存储动态 HTML。之后,我们创建了一个列表“ul”,然后迭代数据,为每个项目创建“li”节点;您可能注意到“for”条件有一个“or”运算符;这允许我们在数据数组结束时或当索引“i”达到将要使用该插件的开发人员定义的“items”属性时停止迭代。
在最后一步中,我们使用“append”方法将 HTML 插入到容器中。
为了使用我们的小部件,我们需要创建“BuzzReader”类的一个实例,但是,在此之前,让我们定义要渲染它的位置。创建一个 HTML 文件,并在 body 元素中添加以下内容:
<div id="buzz"> <div> <div class="reader"></div> </div> </div>
我们将使用类“reader”在 div 内渲染我们的小部件,让我们按如下方式创建小部件的实例:
$(function(){ new BuzzReader({ renderTo : "#buzz .reader", user : "nettutsblog", items : 3 }); });
不要忘记将 jQuery 库和“buzz-widget.js”导入到您的 HTML 文件中。如果所有内容均已正确配置和编码,您应该会看到类似于下图的内容:
好吧,我们现在可以看到更新,但看起来不太漂亮;我们需要对其进行一些样式设置。
/* step 1 */ body{font-family:"Trebuchet MS",Arial,sans-serif;line-height:24px;font-size:14px;} /*Step 2*/ #buzz{width:300px;margin:100px auto;border:1px solid #AFAFAF;} #buzz > div{background-color:#E4E4E4;border:1px solid #F6F6F6;padding:10px;} #buzz .reader{height:350px;overflow:auto;border:1px solid #F6F6F6;padding:80px 10px 10px 10px;background:#fff url(title.jpg) center 0 no-repeat;} /* Step 3 */ #buzz ul{margin:0;padding:0;} #buzz ul li{list-style-type:none;color:#A3A3A3;border-bottom:1px solid #E4E4E4;margin-bottom:5px;padding-bottom:5px;} #buzz ul li div{color:#777;} #buzz ul li a{color:#444;text-decoration:none;font-weight:normal;} #buzz ul li a:hover{text-decoration:underline;} #buzz ul li span{float:right;} /* Step 4*/ #buzz .buzz-loading{position:absolute;margin-left:240px;width:16px;height:16px;background:transparent url(ajax-loader.gif) center center no-repeat;}
在前两步中,我们将小部件置于屏幕中央,并设置容器的大小、边框和颜色;我们还添加了徽标作为小部件的标题。
在最后两个步骤中,我们将样式设置为动态列表,更改了字体的颜色,并向链接添加了一些边距、边框和填充。
因此,我们拥有了更具吸引力的产品。
本教程的最后一步是创建 jQuery 插件。让我们修改“buzz-widget.js”文件,将以下代码添加到文件末尾。
jQuery.fn.buzzReader = function(options){ //Step 1 return this.each(function(){ var opts = options || {}; //Step 2 opts.renderTo = this; new BuzzReader(opts); //Step 3 }); };
在第一步中,我们简单地命名了我们的插件。
在第二步中,如果参数“options”为空,我们将创建配置对象。接下来,我们将属性“renderTo”定义为实际元素。
在第三步中,我们创建了小部件的一个新实例。
现在,我们可以在 HTML 中使用我们的插件,如下所示:
$(function(){ $("#buzz .reader").buzzReader({ user : "nettutsblog", items : 3 }); });
我希望您已经了解了如何从 XML 文档中提取数据以及如何在任何网站上显示最新动态。任何问题?感谢您的阅读!
以上是创建一个小部件来展示您令人兴奋的更新的详细内容。更多信息请关注PHP中文网其他相关文章!