腾讯微博后来居上,据说用户活跃度已超新浪微博。
腾讯微博页有一点很让我喜欢,那就是将鼠标放到用户头像上一会儿,就会在头像上出现一个小的窗口,显示用户的一些资料及其它信息。如右图,这样可以及时方便快速的查看自己及其他人一些相关的信息。
所以我便copy了它的这个功能,整合到了wordpress主题上。
效果如你在我博客评论列表处,你可以直接点击评论者头像,或者将鼠标放到头像上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”…一行。
这串字符从何而来呢?其实是我修改了评论模板,加上了下面这个
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~)
