这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
这篇文章主要介绍了 js 实现仿微博滚动显示信息的效果, 通过由上往下滚动来实现不断显示微博的,而且每一天新微博都是通过淡入效果显示的, 需要的朋友可以参考下
相信大家空闲的时候都会上上微博,推特等社交网站,每次我登陆微博时,我都会留意一下它有什么变化,小的有一些布局的变化,大的有 API 接口的改变等。
在首页登陆微博时,我们可以看到一栏 "大家正在说",它滚动显示着当前每个人发送的微博;刚看到这个效果觉得挺有趣的,所以我们将在接下来的文中介绍实现滚动显示微博信息的效果。
我们细细观察了微博的 "大家正在说",它是通过由上往下滚动来实现不断显示微博的,而且每一天新微博都是通过淡入效果显示的。
图 1 微博 "大家正在说"
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: ''
- };
2、发送跨源请求 我们可以通过发送 ajax 请求方式来调用微博搜索接口,如果请求成功服务器会给程序返回 JSON 格式数据,那么我们需要把返回的数据呈现到页面中。
- $.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 is
- var $script = $(document.getElementsByTagName('head')[0].firstChild);
- var url = $script.attr('src') || '';
- // Gets callback function
- var cb = (url.match(/callback=(\w+)/) || [])[1];
- if (!cb)
- return; // bail
- var 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() 方法并且在请求成功后把数据显示到页面中。
3、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 数据显示到页面中。
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_on
- try { el.style.removeAttribute('filter'); } // ie cleartype fix
- catch (smother) { }
- @*/
- // append the last weibo item first.
- $el.css(opts.css['tweet']).hide().prependTo($cont);
- // Fade in display new item.
- $el.fadeIn(opts.animInSpeed);
- // Loop
- setTimeout(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_on
- try { el.style.removeAttribute('filter'); } // ie cleartype fix
- catch (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 styling
- a: {
- 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 程序界面
现在,我们已经实现了微博搜索插件,搜索 "情人节" 和 "元宵节" 话题下的微博,通过该插件我们获取了微博信息并且显示到页面中。
来源: http://www.phperz.com/article/17/0624/267975.html