1.1.1 摘要

相信大家空闲的时候都会上上微博,推特等社交网站,每次我登陆微博时,我都会留意一下它有什么变化,小的有一些布局的变化,大的有API接口的改变等。

在首页登陆微博时,我们可以看到一栏“大家正在说”,它滚动显示着当前每个人发送的微博;刚看到这个效果觉得挺有趣的,所以我们将在接下来的博文中介绍实现滚动显示微博信息的效果。

目录

  • 定义微博插件
  • 发送跨源请求
  • JSON数据处理
  • 微博相对时间
  • 微博动态效果

1.1.2 正文

我们细细观察了微博的“大家正在说”,它是通过由上往下滚动来实现不断显示微博的,而且每一天新微博都是通过淡入效果显示的。

图1 微博“大家正在说”

定义微博插件

接下来,我们将定义一个插件用来获取某话题下的微博,这里我们将使用jQuery的扩建功能来定于一个微博的jQuery插件

由于jQuery提供了一种机制:让用户给核心模块增加自定义的方法和额外的功能;通过这种机制,jQuery允许我们创建自定义的插件封装常用的方法,从而提高我们的开发效率。

首先,我们通过定义自执行的函数(IIFE),然后把jQuery对象作为参数传递给该自执行函数,通过建立“$”和jQuery的对应关系,这样“$”就不会在其执行范围内被其他库覆盖了。

// Defines a jquery plugin.
; (function($) {$.fn.weiboSearch = function() {// your plugin logic};
})(jQuery);

上面,我们定义一个自执行函数(IIFE),并且在它里面定义了一个扩展方法weiboSearch()。

由于,微博API 2.0提供了一个接口search/topics来搜索某一话题下的微博,如果请求成功则返回JSON格式的数据。

图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: ''
};

发送跨源请求

我们可以通过发送ajax请求方式来调用微博搜索接口,如果请求成功服务器会给程序返回JSON格式数据,那么我们需要把返回的数据呈现到页面中。

/**
* Sends cross origin request with ajax and jsonp.
* @param s
* The params need to send to server.
* For instance, url, appkey, q or count and so forth.
*/
$.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的形式实现跨域访问。

接下来,我们在方法$.fn.weiboSearch()中定义私有方法grabWeibos(),它负责调用getJSONP()方法并且获取返回的JSON数据显示到页面中。

/**
* 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()方法并且在请求成功后把数据显示到页面中。

JSON数据处理

现在,我们基本实现了jquery.weibo.search.js插件,用来搜索某一话题下的微博的功能,由于时间的关系我们已经把界面设计好了,具体的HTML代码如下:

<!-- 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()函数实现微博加载时淡入和清除时淡出的效果。

接着,我们使用$.each()方法遍历JSON数组中的每条微博信息,然后把它们添加到页面DOM中。

图7 微博信息

我们通过跨源请求调用微博search/topics接口,然后把服务器返回的JSON数据显示到页面中。

微博相对时间

现在,基本实现了jquery.weibo.search.js插件了,但我们发现每条微博显示时间好像不太正常,而且还没有实现滚动(animate)和淡入(fadeIn)效果。

由于微博是使用相对时间来表示微博插件时间,当然我们也可以显示具体时间,接下来,让我们把微博创建时间(created_at)转化为相对时间的形式,由于微博的时间格式为:“Thu Feb 14 20:33:30 +0800 2013”,所以我们定义了方法relativeTime()把微博时间转换为相对时间。

// Reference: http://www.w3school.com.cn/js/jsref_obj_regexp.asp
// https://twitter.com/javascripts/blogger.js
// Time format pretty function.
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计算相对时间

微博动态效果

上面,我们通过方法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属性。

接着,我们需要把滚动到最后的微博重新插入到当前第一条微博上,然后通过fadeIn()函数实现微博淡入显示。

现在,我们基本实现了微博“大家正在说”的向下滚动和淡入效果了,我们先用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开始变化。

现在,我们已经实现了淡出、淡入以及滚动效果了,接下来我们需要给界面添加CSS样式让程序更加美观。

// 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 程序界面

现在,我们已经实现了微博搜索插件,搜索“情人节”和“元宵节”话题下的微博,通过该插件我们获取了微博信息并且显示到页面中。

1.1.3 总结

在本博文中,我们通过实现仿微博“大家正在说”的例子,介绍了定义jQuery插件(请参考《自定义jQuery插件Step by Step》)、发送跨源请求、调用新浪微博API和处理JSON数据格式(请参考《Ajax与JSON的一些总结》)等知识。

由于微博API限制了每小时的请求次数和微博数量,所以通过Cache方式把数据先储存到本地(具体请参考这里和这里)。

参考

  • http://jquery.malsup.com/twitter/
  • http://stackoverflow.com/questions/13107536/jquery-handler-error-is-not-a-function
  • http://stackoverflow.com/questions/2845981/jquery-difference-between-functionname-and-fn-functionname
  • http://open.weibo.com/wiki/2/statuses/querymid
  • http://api.jquery.com/fadeOut/
  • http://api.jquery.com/animate/
  • http://api.jquery.com/fadeIn/

Demo下载

仿新浪微博大厅“大家正在说”功能的实现相关推荐

  1. JS实现仿新浪微博大厅和腾讯微博首页滚动效果_前端开发

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  2. 新浪微博 头像上传 php,使用canvas实现仿新浪微博头像截取上传功能_javascript技巧...

    最近看到微博头像上传功能很感兴趣,于是就使用canvas写了一个,本文写的不好还请见谅.本程序目前在谷歌浏览器和火狐浏览器测试可用,ie浏览器无法支持. 因为ie的安全机制不允许img使用本地路径,所 ...

  3. html头像裁剪仿微信,使用canvas实现仿新浪微博头像截取上传功能

    最近看到微博头像上传功能很感兴趣,于是就使用canvas写了一个,本文写的不好还请见谅.本程序目前在谷歌浏览器和火狐浏览器测试可用,ie浏览器无法支持. 因为ie的安全机制不允许img使用本地路径,所 ...

  4. 仿新浪微博滚动,无文字渐显功能

    又一款仿新浪微博的文字滚动功能,去掉了滚动开始时候的文字渐显效果,似乎更明淅了,又一种风格的新浪微博大厅文字滚动,要的就复制代码吧. <!DOCTYPE HTML> <html la ...

  5. 新浪微博发布文章html,JS实现仿新浪微博发布内容为空时提示功能代码

    本文实例讲述了JS实现仿新浪微博发布内容为空时提示功能.分享给大家供大家参考.具体如下: 这里使用JavaScript模拟新浪微博的一个功能,在发布微博的内容为空时,文本框提醒用户这里没有输入内容,本 ...

  6. 仿新浪微博的ListView下拉更新功能

    由于最近做的项目中也用到了这个功能,今天刚好实现了下,就趁现在有时间写篇博客分享下.在做的时候也参考了下别人的代码,毕竟站在巨人的肩膀上才会是自己更加强大.哈哈!先看看新浪的下拉更新是什么样的吧! O ...

  7. js仿新浪微博消息发布功能

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. 【原生JS】仿新浪微博名片弹框

    [原生JS]仿新浪微博名片弹框  博客已经搬家地址:http://cm2009.sinaapp.com/ 第一次用原生JS写小功能,有很多不足的地方,例如事件绑定没有使用事件委托功能,而是直接用零级D ...

  9. 仿新浪微博的插入#话题#

    最近看到其他网上有写仿新浪微博插入话题这个功能,具体就是当用户输入"#"这个字符以后,会跳出一个选项让用户选择一个话题,然后在输入框中会显示#XX话题#,点击删除会一下把整个话题删 ...

最新文章

  1. linux yum list包数量少,Linux基础知识之YUM包管理工具
  2. 纯真IP地址数据库qqwry.dat解析
  3. hbuilder怎么做登录界面_hbuilder 第三方登录实例
  4. Delphi 记录类型- 结构指针
  5. arima模型 p q d 确定_自回归移动平均模型(ARMA)
  6. 周鸿祎:物联网时代的三大威胁
  7. 恢复 混淆后的 stacktrace 文件
  8. 为什么很多人赚不到钱?
  9. Redis进阶实践之一VMWare Pro虚拟机安装和Linux系统的安装
  10. 浙江大学-包家立计算生物学1
  11. sql limit offset 的用法 但在SqlServer中用不了
  12. 服务器远程桌面日志,Windows记录远程桌面3389登录日志
  13. 华为emui3.1 android,华为EMUI3.1
  14. 《道德经》里的世界观(一种解读,仅供参考)
  15. linux下编译qt chart,QT Charts入门
  16. 从零开始写第一个Android应用程序
  17. 现在40系显卡都快出来了,为何1060型号的显卡还有这么多人用?
  18. 公众号怎么设置滑动文字_微信公众号滑动文字怎么制作内容呢?
  19. JAVA高级工程师笔试面试题
  20. Java——图片格式转换

热门文章

  1. 【蓝桥杯嵌入式主板(G4)】第一章 软件环境搭建
  2. 戴尔Inspiron 3543(灵越)安装固态硬盘操作说明
  3. 2022年中级会计实务考试精选复习题及答案
  4. 2021-2027全球与中国光纤收发器市场现状及未来发展趋势
  5. parasolid 原因 效率_PARASOLID 25.0提供众多用户驱动型增强特性 助力提升工作效率...
  6. Excel公式系列: 单元格中字符是否包含某个特定值IF、ISERROR、FIND
  7. 世恒易语言百集教程在线观看.非常好的易语言入门教程哦
  8. PyQt(Python+Qt)学习随笔:复选框checkBox的tristate属性
  9. dmg后缀的文件怎么在windows上运行
  10. 【无标题】2022年10月22日 20点 程序爱生活 纳指和恒指反弹的概率还在,但是反弹做空为主。敏感因子第一次出现折价缩小,或许春天不太远,还需要观察!