
图1 微博“大家正在说”
1、定义微博插件
接下来,我们将定义一个插件用来获取某话题下的微博,这里我们将使用jQuery的扩建功能来定于一个微博的jQuery插件
由于jQuery提供了一种机制:让用户给核心模块增加自定义的方法和额外的功能;通过这种机制,jQuery允许我们创建自定义的插件封装常用的方法,从而提高我们的开发效率。
首先,我们通过定义自执行的函数(IIFE),然后把jQuery对象作为参数传递给该自执行函数,通过建立“$”和jQuery的对应关系,这样“$”就不会在其执行范围内被其他库覆盖了。
// Defines a jquery plugin.; (function($) {$.fn.weiboSearch = function() {// your plugin logic};})(jQuery);上面,我们定义一个自执行函数(IIFE),并且在它里面定义了一个扩展方法weiboSearch()。
图2微博搜索接口参数
通过上图,我们知道微博搜索接口需要提供应用的AppKey(非OAuth授权方式)和话题关键字(q)。
接下来,我们定义了一个字面量对象defaults,它包含微博接口的url、应用的AppKey、话题关键字(q)和单页返回的记录条数(count)等属性,具体定义如下:
// Defines weibo defaults type.$.fn.weiboSearch.defaults = {url: "https://api.weibo.com/2/search/topics.json?q=",appKey: "5786724301",numWeibo: 15,term: ""};2、发送跨源请求 $.getJSONP = function(s) {// Due to cross origin request, so we to use jsonp format.s.dataType = "jsonp";$.ajax(s);// figure out what the callback fn isvar $script = $(document.getElementsByTagName("head")[0].firstChild);var url = $script.attr("src") || "";// Gets callback functionvar cb = (url.match(/callback=(w+)/) || [])[1];if (!cb)return; // bailvar t = 0, cbFn = window[cb];$script[0].onerror = function(e) {$script.remove();handleError(s, {}, "error", e);clearTimeout(t);};if (!s.timeout)return;window[cb] = function(json) {clearTimeout(t);cbFn(json);cbFn = null;};// Gets time out function flag.t = setTimeout(function() {$script.remove();handleError(s, {}, "timeout");if (cbFn)window[cb] = function() {};}, s.timeout);/*** Fix issue: "jQuery.handleError is not a function"*/function handleError(s, xhr, msg, e) {s.error && s.error.call(s.context, xhr, msg, e);s.global && $.event.trigger("ajaxError", [xhr, s, e || msg]);s.complete && s.complete.call(s.context, xhr, e || msg);}};上面,我们定义了方法getJSONP(),它通过发送ajax请求的方式调用微博API,这时我们需要跨源请求数据,我们可以通过JSONP格式获取跨源数据,由于它允许在服务器端集成Script tags返回至客户端,通过Javascript callback的形式实现跨域访问。/*** Uses ajax request to grab weibos.*/function grabWeibos() {var url = opts.url;grabFlag = false;grabbing = true;$.getJSONP({url: url,timeout: 30000,data: {source: opts.appKey,q: opts.term,count: opts.numWeibo},error: function(xhr, status, e) {},complete: function() {},success: function(json) {if (json.error) {// Can"t get results displays error.return;}// iterates weibo results$.each(json.data.statuses, function(i) {// Adds data to page.})}});}上面,我们定义了grabWeibos(),它调用了getJSONP()方法并且在请求成功后把数据显示到页面中。<!-- From design--><!DOCTYPE html><html><head><meta content="text/html; charset=utf-8" http-equiv="Content-Type"><title></title><link rel="stylesheet" type="text/css" href="css/weibo.serach.style.css"></head><body><table><tbody><tr><td><div id="weibo1" class="weibo"></div></td><td><div id="weibo2" class="weibo"></div></td></tr></tbody></table></body></html>接下来,我们在页面代码中引用jQuery库和自定义微博话题搜索插件jquery.weibo.search.js,具体代码如下:
<!-- Adds Javascript reference --><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script><script type="text/javascript" src="js/jquery.weibo.search.js"></script>上面,我们直接引用Google提供的jQuery库,当然我们也把jQuery库下载到本地,然后引入到项目中,接下来我们在head元素中添加调用微博话题搜索插件的代码,具体代码如下:
<!-- When document ready invokes charCount function--><script type="text/javascript">// Invokes webioSearch function.$(document).ready(function () {$("#weibo1").weiboSearch({term:"情人节",direction:"down"});$("#weibo2").weiboSearch({term:"元宵节",direction:"up"});});</script>上面,我们在页面中调用了weiboSearch()的默认方法,并且搜索“情人节”话题下的微博。接下来,我们打开Chrome中Network选项,查看search/topics中的请求包含了source、count、q和callback(回调函数)参数。
图3 Ajax请求
由于Chrome中的JSON数据没有换行不便于查看,所以我们在Firefox中查看返回的JSON格式的数据。

图4微博JSON数据
上面的JSON数据不便于查看,这里我们使用JSON viewer格式化微博数据,格式化后的数据如下:

图5格式化的JSON数据
通过上图,我们发现微博数据包含在try/catch语句中,如果请求成功catch中将为空,反之,返回相应的错误提示信息。
接下来,我们把微博数据提取出来,然后去掉try/catch我们在JSON viewer中查看微博数据的结构。

图6 微博JSON数据
通过上图,我们知道返回数据是一个JSON数组,它的大小是根据我们的请求参数count决定的,而且微博规定每个请求最多返回200条微博。
接下来,我们需要把数据显示到页面中,现在让我们实现success方法吧!具体代码如下:
// Gets response data from weibo api.success: function(json) {if (json.data.error) {// Can"t get data displays error.failEye(json.data.error);return;}// Emptys contain with fade out effect.$cont.fadeOut("fast", function() {$cont.empty();// iterates weibo results$.each(json.data.statuses, function(i) {if (!opts.filter.call(opts, this) || this.truncated)return; // skip this weibo, some weibos may be deleted.var $img, $text, w,tweet = opts.formatter(this, opts),$tweet = $(tweet);// Weibo data.$tweet.css(opts.css["tweet"]);$img = $tweet.find(".weiboSearchProfileImg").css(opts.css["img"]);$tweet.find(".weiboSearchUser").css(opts.css["user"]);$tweet.find(".weiboSearchTime").css(opts.css["time"]);$tweet.find("a").css(opts.css["a"]);$tweet.appendTo($cont);$text = $tweet.find(".weiboSearchText").css(opts.css["text"]);if (opts.avatar) {w = $img.outerWidth() + parseInt($tweet.css("paddingLeft"));$text.css("paddingLeft", w);}})// Loads weibos with fade in effect.$cont.fadeIn("fast");// Invokes weibo api again.if (json.data.statuses.length < 2) {if (opts.refreshSeconds)setTimeout(gradWeibos, opts.refreshSeconds * 1000);return;}});}在success()方法中,我们使用了jQuery的fadeIn()和fadeOut()函数实现微博加载时淡入和清除时淡出的效果。
图7 微博信息
我们通过跨源请求调用微博search/topics接口,然后把服务器返回的JSON数据显示到页面中。
5、微博相对时间
现在,基本实现了jquery.weibo.search.js插件了,但我们发现每条微博显示时间好像不太正常,而且还没有实现滚动(animate)和淡入(fadeIn)效果。
由于微博是使用相对时间来表示微博插件时间,当然我们也可以显示具体时间,接下来,让我们把微博创建时间(created_at)转化为相对时间的形式,由于微博的时间格式为:“Thu Feb 14 20:33:30 +0800 2013”,所以我们定义了方法relativeTime()把微博时间转换为相对时间。
function relativeTime(dateString) {var values = dateString.split(" ");dateString = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];var parsed_date = Date.parse(dateString);var relative_to = (arguments.length > 1) ? arguments[1] : new Date();var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);delta = delta + (relative_to.getTimezoneOffset() * 60);if (delta < 60) {return "just now";} else if (delta < 120) {return "a minute ago";} else if (delta < (60 * 60)) {return (parseInt(delta / 60)).toString() + " minutes ago";} else if (delta < (120 * 60)) {return "about an hour ago";} else if (delta < (24 * 60 * 60)) {return "about " + (parseInt(delta / 3600)).toString() + " hours ago";} else if (delta < (48 * 60 * 60)) {return "1 day ago";} else {return (parseInt(delta / 86400)).toString() + " days ago";}}上面,我们定义了方法relativeTime(),首先它通过拼接方式转换时间格式为“Feb 14, 2013 20:33:30”,然后把dateString转换为Date,接着获取当前时间减去微博时间(created_at)计算出相对时间(delta)。
图8 relativeTime计算相对时间
5、微博动态效果
上面,我们通过方法relativeTime()把微博的时间转换为相对时间,接下来,我们需要实现微博的滚动(animate)和淡入(fadeIn)效果。
在新浪微博大厅里,我们可以看到“大家正在说”中每条微博由上往下地滚动着,其实要实现该滚动效果我们可以使用jQuery的animate()方法,具体实现如下:
/*** Weibos rolling from top to bottom*/function weiboIn() {if (paused || grabbing) {setTimeout(weiboIn, 500);return;}// Gets last element.var h, $el = $cont.children(":last"), $elFirst = $cont.children(":first");// Gets last weibo item height.h = $el.outerHeight();// Animate: increases the first weibo item margin top to "h".// Then decreases the first weibo item margin top to "0".$elFirst.animate({ marginTop: h }, opts.animInSpeed, function() {$elFirst.css({ marginTop: 0, opacity: 1 });/*@cc_ontry { el.style.removeAttribute("filter"); } // ie cleartype fixcatch (smother) { }@*/// append the last weibo item first.$el.css(opts.css["tweet"]).hide().prependTo($cont);// Fade in display new item.$el.fadeIn(opts.animInSpeed);// LoopsetTimeout(grabFlag ? grabWeibos : weiboIn, opts.timeout);});}上面,我们定义了weiboIn()方法,它实现微博由上往下滚动显示效果,我们通过animate()方法动态地修改div元素的marginTop属性。/*** Weibos rolling from bottom to top.*/function weiboOut() {if (paused || grabbing) {setTimeout(weiboOut, 500);return;}// Gets last element.var h, $el = $cont.children(":first"), el = $el[0];// Implements fade out effect. $el.animate(opts.animOut, opts.animOutSpeed, function() {// Gets first weibo item height.h = $el.outerHeight();$el.animate({ marginTop: -h }, opts.animInSpeed, function() {$el.css({ marginTop: 0, opacity: 1 });/*@cc_ontry { el.style.removeAttribute("filter"); } // ie cleartype fixcatch (smother) { }@*/// append the last weibo item last.$el.css(opts.css["tweet"]).show().appendTo($cont);setTimeout(grabFlag ? grabWeibos : weiboOut, opts.timeout);});});}在weiboOut()方法中,我们通过修改$el的opacity属性实现淡出效果,当然我们也可以使用fadeOut()方法实现淡出,同样我们使用方法animate()修改marginTop属性,不同的是从-h开始变化。// Weibo css style in jquery plugin.css:{// default stylinga:{ textDecoration:"none", color:"#3B5998" },eye:{ width:"40px", height:"40px", position:"absolute", left:"-30px", top:"-20px", border:"none" },container:{ overflow:"hidden", backgroundColor:"#eee", height:"100%" },fail:{ background:"#6cc5c3 url(./images/error_page_small.png) no-repeat 50% 50%", height:"100%", padding:"10px" },frame:{ border:"10px solid #C2CFF1", borderRadius:"10px", "-moz-border-radius":"10px", "-webkit-border-radius":"10px" },tweet:{ padding:"5px 10px", clear:"left" },img:{ "float":"left", margin:"5px", width:"48px", height:"48px" },loading:{ padding:"20px", textAlign:"center", color:"#888" },text:{},time:{ fontSize:"smaller", color:"#888" },title:{ backgroundColor:"#C2CFF1", margin:0, padding:"0 0 5px 0", textAlign:"center", fontWeight:"bold", fontSize:"large", position:"relative" },titleLink:{ textDecoration:"none", color:"#3B5998" },user:{ fontWeight:"bold" }}然后,我们weibo.serach.style.css文件中添加以下样式,具体定义如下:div.weibo { margin: auto; width: 300px }#weibo1 { height: 300px;}#weibo2 { height: 300px; }body { background-color: white }body, div { font-family: "微软雅黑", helvetica, verdana, arial, sans-serif }body { margin: 20px 0; padding: 0; font-size: small; color: #333 }div {display: block}/* Image rounded corner*/.weiboSearchProfileImg{border-radius: 10px;-moz-border-radius: 10px;-webkit-border-radius: 10px;}table {margin: auto;border-collapse: separate;border-spacing: 25px;}table {border-collapse: collapse;}
图9 程序界面
现在,我们已经实现了微博搜索插件,搜索“情人节”和“元宵节”话题下的微博,通过该插件我们获取了微博信息并且显示到页面中。
以上就是本文的全部内容,希望对大家学习有所帮助。