八月
16

仿腾讯微博式访客信息悬浮显示(JavaScript & ajax)

12腾讯微博后来居上,据说用户活跃度已超新浪微博。

腾讯微博页有一点很让我喜欢,那就是将鼠标放到用户头像上一会儿,就会在头像上出现一个小的窗口,显示用户的一些资料及其它信息。如右图,这样可以及时方便快速的查看自己及其他人一些相关的信息。

所以我便copy了它的这个功能,整合到了wordpress主题上。

434效果如你在我博客评论列表处,你可以直接点击评论者头像,或者将鼠标放到头像上2s,就会出现loading图标,从后台获取数据后就会出现一个长方形框,显示了当前评论者的头像,姓名,邮箱和所用的操作系统、浏览器等信息。另外头像下方是评论者所用的邮箱在我博客所发表过的评论的总数。邮箱我将前三位转为*号了,因为隐私的关系。其实这种后期请求过来的数据,是不会被搜索引擎及各种抓取工具捕获的,所以不存在邮箱账号会被采集到,被滥发垃圾邮件的危险,我即使直接显示了也没关系的。

前台JS处理时还要注意一点,那就是避免重复查询,因为一个页面上可能出现一个用户评论过多次的情况,那么如果鼠标放到这个用户的每条评论的头像上都向服务器发送查询的话,那么就很浪费了。但是,这些访客又没有在博客注册,没有一个唯一的ID能代表其身份。唯一可以证明其身份的就是邮箱了,但是邮箱又不能直接公布,所以我将每个访客的邮箱通过md5加密后的字串的前十位当做这个访客的唯一ID。在对一个访客信息查询后,将这个显示信息div的id标记为访客ID。如果后面再将鼠标放到同一位访客头像上,则会在页面上寻找这个具有唯一id值的信息显示div,如果找到了就直接显示这个div了,不必再次发送查询。其实腾讯微博的做法是在每条微博的<li>标签中加入一个具有唯一字串的rel属性,每个用户具有唯一的字串。它是通过这个字串来标识不同的用户的。
这个到底该怎么做呢?首先当然是获取页面上每个评论了。然后再对头像上的鼠标移上事件设置动作监听addcard

   1: (function(){
   2: //一些打包的简便方法
   3:     function $(id) {//根据ID获取对象
   4:         return document.getElementById(id)
   5:     }
   6:     function $$(c, t, p) {//根据class值获取对象数组
   7:         var at = p.getElementsByTagName(t);
   8:         var ms = new Array();
   9:         var r = new RegExp('(^|\\s)' + c.replace(/\-/g, '\\-') + '(\\s|$)');
  10:         var e;
  11:         for (var i = 0; i < at.length; i++) {
  12:             e = at[i];
  13:             if (r.test(e.className)) {
  14:                 ms.push(e)
  15:             }
  16:         }
  17:         return ms
  18:     }
  19:     function removeNode(obj){//移除页面某一节点
  20:         if(typeof obj == "string")$(obj).parentNode.removeChild($(obj));
  21:         else obj.parentNode.removeChild(obj);
  22:     }
  23:     function insertBe(obj,tar){//在一个节点前插入另一个节点
  24:         tar.parentNode.insertBefore(obj,tar);
  25:     }
  26:     function insertAf(obj,tar){//在一个节点后插入另一个节点
  27:         tar.parentNode.insertBefore(obj,tar.nextSibling);
  28:     }
  29:     function addListener(element, name, observer, useCapture) {//设置监听
  30:         if (element.addEventListener) {
  31:             element.addEventListener(name, observer, useCapture)
  32:         } else if (element.attachEvent) {
  33:             element.attachEvent('on' + name, observer)
  34:         }
  35:     }
  36:     //
  37:     var lis = $$('comment', 'li', $('thecomments'));//取得页面上div#thecomments下具有class=comment的li标签集合li.comment
  38:     for (var i = 0; i < lis.length; i++) {
  39:     (function() {
  40:         var id = lis[i].id,it;
  41:         if (/^li-comment\-[0-9]+$/.test(id)) {
  42:             var avatar=$$('avatar', 'img', $(id))[0];
  43:             addListener(avatar,'mouseover',function(){addcard(id,it)},false);//设置监听
  44:         }
  45:     })();
  46:     }
  47: //...代码未完,继续向下看
  48: })();

addcard()具有两个参数,一个是这条评论的id,一个是个定时器。我们就是根据id来发送请求的。接下来是发送请求了。

   1: function addcard(id,it){
   2:         clearTimeout(it);//先清除下定时器
   3:         if(document.getElementsByTagName('ucard')||0){//先将页面上所有未消失的信息显示框都隐藏
   4:             var ucards=$$('ucard','div',$('thecomments'));
   5:             for(var i=0;i<ucards.length;i++)
   6:                 if(ucards[i].style.display=='block')
   7:                     ucards[i].style.display='none';
   8:         }
   9:         id=id.replace('li-comment-','');
  10:         var ucard,cardid=$('comment-'+id).className;
  11:         if($(cardid)||0){//如果页面上存在具有唯一cardid的div,就直接将它移动到目标位置,设置display,让它显示出来
  12:             ucard=$(cardid);
  13:             insertBe(ucard,$('li-comment-'+id).firstChild);
  14:             ucard.style.display="block";
  15:             addListener(ucard,'mouseout',function(){delcard(cardid,it)},false);//设置鼠标移下动作监听
  16:         }else{
  17:             ucard=document.createElement('div');ucard.className='ucard small';ucard.style.display="block";ucard.id=cardid;//将信息框的id值设置为唯一cardid
  18:             it=setTimeout(function(){//定时1.5s后发送查询请求
  19:                 var xmlHttp,url='?action=showCard&id='+id;//创建xmlhttp对象,url的主要参数是id,后台就是根据id从数据库中获取数据返回前台的
  20:                 try {
  21:                     xmlHttp = new XMLHttpRequest()
  22:                 } catch(e) {
  23:                     try {
  24:                         xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")
  25:                     } catch(e) {
  26:                         try {
  27:                             xmlHttp = new ActiveXObject("Msxml2.XMLHTTP")
  28:                         } catch(e) {
  29:                             alert("Your browser does not support ajax!");
  30:                             return false;
  31:                         }
  32:                     }
  33:                 }
  34:                 xmlHttp.open("GET", url, true);
  35:                 xmlHttp.setRequestHeader("Content-type", "charset=UTF-8");
  36:                 xmlHttp.onreadystatechange = function() {
  37:                     if (xmlHttp.readyState == 4 || xmlHttp.readyState=="complete") {
  38:                         if (xmlHttp.status == 200) {
  39:                             var data = xmlHttp.responseText;
  40:                             ucard.className=ucard.className.replace(/ small/,'');
  41:                             ucard.innerHTML=data;//将数据填入这个div中
  42:                         } else {
  43:                             removeNode(ucard);//获取数据失败就移除这个节点
  44:                         }
  45:                     }
  46:                 };
  47:                 xmlHttp.send(null);
  48:                 insertBe(ucard,$('li-comment-'+id).firstChild);//将节点插入到评论li标签下的第一个节点前面
  49:                 addListener(ucard,'mouseout',function(){delcard(cardid,it)},false);
  50:             },1500);
  51:         }
  52:     }
  53:  
  54: function delcard(cardid,it){//使信息框隐藏,这样处理目前有些问题,我换了一种方式,代码很多,下次再说,这里还是用原始方法吧
  55:     clearTimeout(it);
  56:     it=setTimeout(function(){
  57:         $(cardid).style.display="none";
  58:     },3000);
  59: }
  60:  
  61: addListener($('thecomments'),'click',function(){//加上点击评论列表区域就隐藏信息显示框
  62:     if(document.getElementsByTagName('ucard')||0){
  63:         var ucards=$$('ucard','div',$('thecomments'));
  64:         for(var i=0;i<ucards.length;i++)
  65:             if(ucards[i].style.display=='block')
  66:                 ucards[i].style.display='none';
  67:     }
  68: },false);

OK,我已经贴出了所有我用到的前端JS代码。上面代码中你已经注意到了cardid=$(‘comment-’+id).className这一句,这句是获取一个class属性值。有什么用呢?其实这个就是标识唯一访客的ID,我事先在评论列表输出时就给相应的div加上了这个class属性,如下图中的<div id=”comment-4143”…一行。

233

这串字符从何而来呢?其实是我修改了评论模板,加上了下面这个

   1: <div id="comment-<?php comment_ID(); ?>" class="<?php echo substr(md5($comment->comment_author_email),0,10) ?>">

将email加密后截断前十位输出。

到这里,我觉得该说的都说完了,至于后台,就看你要往前台输出显示什么信息了。其实我想也不会有几个人想要去折腾这个,我给出前台JS代码仅作参考,你可以修改用于其它用途。


昨天在书写这篇文章时不小心发出去了,结果木木winy已经过来抢了沙发,我由于网络问题,删除慢了一拍,等我删完回过头来才在邮箱里看到二人抢沙发的邮件,杯具了。二人的沙发被我收走了。。。

最后展示一下自我使用wordpress以来所有评论者中评论数最多的人,我没专门去查询过这个,只是在做这个资料显示功能是,按email统计了每个email的评论数,我在前台看了几个人的,发现应该是zwwooooo小邪的评论最多,位于前两位,到本文发表时分别是88条和76条。你也可以查看你自己的相关信息,只要点击自己的头像或者将鼠标放到自己头像上就行了。当然,一般是展示前三名,但其实第一名是我了,你们查看我的会显示评论:N条,哈哈,评论统计大于100条就不再显示具体条熟了,只显示N条。嗯,都过N的人多了,我再分等级,评论也能升级了。想要显示N条,那就努力评论到100条吧。(下图前两位是评论数最多,后两位是今天被我收走沙发的两位同学O(∩_∩)O~)

11111

本文标签: , , , , , ,

分享

本文短网址: http://qiqi.boy.im/7j

这篇文章已经有 115 条评论

Comments (113) Trackbacks (2)
You can leave a response or Trackback this entry .
  1. Fanr -#41

    这个存成js评论那里怎么调用呢?直接引入这个js就好?

  2. 梦画 -#42

    上面的代码全贴了,怎么没有效果呢,求完整的js文件和demo

  3. 天空之城 -#43

    楼主求完整的js文件和demo,俺的邮箱:347071765@qq.com

  4. 华崽 -#44

    LZ ,请教下这个房腾讯微博信息提示的问题呢,看见了请回复,谢谢

  5. 154 -#45

    ¡

  6. chology -#46

    rt

  7. chology -#47

    请问你这个评论框是怎么制作的??而且不用登录也可以评论你的文章诶!!

  8. 老衲 -#48

    看了好几篇wordpress的文章对于我来说很有技术含量,顶一下博主,潜水什么的太不好意思了

  9. 119977 -#49

    :shock: 发不了代码

  1. WordPress折腾记事 / IM路人

    [...] 2、看了qiqiboy《仿腾讯微博式访客信息悬浮显示》之后,也想弄一个这样的效果。 [...]

  2. Hello WordPress!

    [...] 2010.08 我继续折腾,期间我修改trackback样式,统一评论外观,也分享了这个修改中的一些涉及到的代码补充《修改trackback样式,统一评论外观》中代码。这期间,我对ajax兴趣逐渐浓厚起来,所以便有了这个博客加入若干Ajax效果。在折腾ajax、延迟加载中,我遇到了页面文档初始化的一些问题,于是查阅文档便有了这篇JavaScript页面文档初始化 window.onload的替代办法;后来,我有了在侧边栏开发ajax即时评论的想法,于是便出现了【效果测试展示篇】Ajax版即时侧边栏评论回复功能,掉了几天大家的胃口,然后又简单的蜻蜓点水般【原理指导篇】无时不在的评论 侧边栏即时回复功能。八月份期间,我的SimPaled主题基本上成型了,于是我将它介绍了给大家【SimPaled篇】Introduce My Blog Theme For You。很哟意思的是,我看到了腾讯微博的头像悬浮显示,于是便仿了下来仿腾讯微博式访客信息悬浮显示(JavaScript & ajax)。基于边栏评论,为了方便大家,我开发了插件发布:边栏最新评论及ajax回复——WP RC Reply AJAX。后来发现wordpress的无限嵌套的邮件回复有问题,于是有了完美解决wordpress无限嵌套<二> 【邮件发送相关问题】。因为SimPaled主题用到了很多延迟加载,所以有同学问我延迟加载怎样实现,于是我分享了自己当时的思路JS延迟加载机制函数(Lazyload)。八月份最后一件事大概要算我在博客中曝光了中文spam里的那些极品好玩的spam吧围观wordpress中文圈内好玩的spam [...]

Leave a Reply

Hi , say something.

  • :?:
  • :razz:
  • :sad:
  • :evil:
  • :!:
  • :smile:
  • :oops:
  • :grin:
  • :eek:
  • :shock:
  • :???:
  • :cool:
  • :lol:
  • :mad:
  • :twisted:
  • :roll:
  • :wink:
  • :idea:
  • :arrow:
  • :neutral:
  • :cry:
  • :mrgreen: