九月
03

我的读者墙展示(附所用JS代码)

好多人都在博客上弄了个读者墙,我之前也搞过,但是换了新主题之后就没再添加了。所以抽了个时间,在links页面加了读者墙,展示的是最近三个月内的评论数量在前72名的访客头像。围观我的读者墙请移步此处

读者墙部分加了个JS效果,鼠标移上去会在旁边打开一个侧滑面板,显示访客的姓名和评论数量等信息。我将这个效果封装了一下,与大家分享。

(:因为涉及到代码的bug修复、代码更新等因素,demo中的代码不会同步更新,所以JS代码以本文中所贴为准。bug修复一: 修正浏览器宽度获取少计算滚动条宽度的问题。)

/*!
 * author: liuqiqi
 * date: 2010/09/01
 */
var Class = {
    create: function() {
        return function() {
            this.init.apply(this, arguments);
        }
    }
}
var PicWall=Class.create();
PicWall.prototype={
 
    init:function(wrapId,infoId,picClass,textClass){
        this.wrap=this.$(wrapId);
        this.info=this.$(infoId);
        this.picClass=picClass;
        this.textClass=textClass;
        this.timer="";
        this.pics=this.$$(this.picClass, 'li', this.wrap)
        for (var i = 0; i < this.pics.length; i++) {//给每张图片加上事件监听
            this.addListener(this.pics[i], 'mouseover', this.bind(this.show,this), false);//用bind给事件函数绑定正确的对象
        }
    },
    
    show:function(e){
        //这里要注意,页面结构li标签下必须是头像图片img,并且不要在img外再加a标签,否则下面这句代码获取不到正确的事件源节点
        var node=e.target?e.target.parentNode:e.srcElement.parentNode;
        this.info.style.display = "block";
        this.info.innerHTML = node.innerHTML;//将图片加到div#info中
        var point = this.getMousePoint(e);//获取事件发生时鼠标坐标
        var picXY = this.getPicXY(node);//获取当前图片的坐标
        var windowx = document.documentElement.clientWidth || document.body.clientWidth;//浏览器可视区域宽高(前者为网页头声明W3C标准后正常获取可视区域宽度,后者为未声明标准情况下IE获取宽度)
        var maxleft = this.getPicXY(this.wrap).x + this.wrap.clientWidth;//alert(maxleft);return; 放置图片列表容器的右边框x坐标
        if (picXY.x + 156 >; maxleft) {//信息框展开后大于容器右边框,则使信息框向左滑动展开
            this.info.style.left = "auto";
            this.info.style.right = windowx - picXY.x - 53 + "px";
            this.addClassName(this.info, 'right');//此处是将头像浮动到右边显示
        }
        else {//正常情况下信息框在右边滑动展开
            this.removeClassName(this.info, 'right');
            this.info.style.right = "auto";
            this.info.style.left = picXY.x - 3 + "px";
        }
        this.info.style.top = picXY.y - 3 + "px";
        this.addListener(this.info, 'mouseout', this.bind(this.unshow,this), false);
        clearInterval(this.timer);
        var starttime=new Date(), nowtime;
        this.timer = setInterval(this.bind(function(){//宽度变换
            nowtime=new Date();
            if (nowtime - starttime < 300) {
                this.info.style.width = 53 + Math.floor((nowtime - starttime)/300*100)/100*103 + "px";
            }
            else {
                clearInterval(this.timer);
                this.$$(this.textClass,'span',this.info)[0].style.display="block";
            }
        },this), 5)
    },
    
    unshow:function(e){
        var node=e.target?e.target.parentNode:e.srcElement.parentNode;
        var point = this.getMousePoint(e);
        var picXY = this.getPicXY(node);
        //通过坐标比对,判断鼠标是否移出信息框区域
        //下面这个if括号语句可以删除,那样鼠标将不能放到文字区域
        if (point.x <; picXY.x || point.x > picXY.x + node.clientWidth || point.y < picXY.y || point.y > picXY.y + node.clientHeight) {
            clearInterval(this.timer);//清除定时器
            this.info.style.display = "none";
            this.info.style.width = "56px";//宽度重置初始化
        }
    },
    
    $:function(id){//由id获取结点对象
        return document.getElementById(id);
    },
    
    $$:function(c, t, p){//c:className, t:tagName, p: praentNode。根据节点的class、结点标签类型、及其父级结点来获取一组符合条件的结点数组
        var at = p.getElementsByTagName(t);
        var ms = new Array();
        var r = new RegExp('(^|\\s)' + c.replace(/\-/g, '\\-') + '(\\s|$)');
        var e;
        for (var i = 0; i < at.length; i++) {
            e = at[i];
            if (r.test(e.className)) {
                ms.push(e)
            }
        }
        return ms
    },
    
    getMousePoint:function(ev){
        var x,y;
        if (typeof window.pageYoffset!= 'undefined') {
            x = window.pageXOffset;
            y = window.pageYOffset
        }
        else 
            if (typeof document.compatMode != 'undefined' &;& document.compatMode != 'BackCompat') {
                x = document.documentElement.scrollLeft;
                y = document.documentElement.scrollTop
            }
            else 
                if (typeof document.body != 'undefined') {
                    x = document.body.scrollLeft;
                    y = document.body.scrollTop
                }
        x += ev.clientX;
        y += ev.clientY;
        return {'x' :x ,'y':y};
    },
    
    getPicXY:function(o){
        var x=y=0;
        do {
            x += o.offsetLeft || 0;
            y += o.offsetTop  || 0;
            o = o.offsetParent;
        } while (o);
 
        return {'x' :x ,'y':y};
    },
    
    bind:function(f,o){
        return function(){
            return f.apply(o,arguments);
        }
    },
    
    hasClassName:function(o, c){//判断o是否具有值为c的className
        return new RegExp("(?:^|\\s+)" + c + "(?:\\s+|$)").test(o.className);
    },
    
    addClassName:function(o, c){//给o添加名为c的className
        if (!this.hasClassName(o, c)) {
            o.className = [o.className, c].join(" ");
        }
    },
 
    removeClassName:function(o, c){//删除o的值为c的className
        if (this.hasClassName(o, c)) {
            var a = o.className;
            o.className = a.replace(new RegExp("(?:^|\\s+)" + c + "(?:\\s+|$)", "g"), " ");
        }
    },
 
    addListener:function(e, n, o, u){//监听设置封装函数
        if(e.addEventListener) {
            e.addEventListener(n, o, u);
            return true;
        } else if(e.attachEvent) {
            e['e' + n + o] = o;
            e[n + o] = function() {
                e['e' + n + o](window.event);
            };
            e.attachEvent('on' + n, e[n + o]);
            return true;
        }
        return false;
    }
}

 

使用这段JS代码,你需要注意下你的页面结构,要在一个固定ID1的div中输出若干li标签,li标签也要有一个className2,然后在li标签中输出头像图片,同样的关于访客的姓名、评论数量也要在li标签下,并且放到一个span标签中,这个span标签页给加个className3,最后在页面中加个显示访客信息的div,ID4固定。

关于页面结构你可以使用firebug或相关工具查看我的友情链接页面的的读者墙的页面结构。也可以下载此demo包。(2010.10.28,原包中代码已经老旧,此处乃最新代码)

页面结构写好了,就可以使用new PicWall()来使用上面的js了,它的四个参数分别是上面的1、2、3、4标注。即最外层的div id,显示信息的div id,li标签的className,li标签下放置的读者信息的span标签的className。比如,我的友链页面的读者墙即使用

   1: new PicWall('commentsWall','info','pic','text');

来调用JS。commenswall是我的读者墙那个大div的id,info是一个空的div的id,pic是li标签的class,text是头像旁的span标签的class。更详细的下载demo包自行查看。CSS样式代码也在demo包里。

效果预览,可查看此处(demo包里也有或者我的友链页面)。

11233

本文标签: , , , ,

分享

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

这篇文章已经有 72 条评论

Comments (70) Trackbacks (2)
You can leave a response or Trackback this entry .
  1. A.shun -#1

    沙发~

  2. Cen -#2

    Wow,四个字,cool,要折腾一下,弄在我的网站,哈哈

  3. Afio -#3

    效果很好。。。但是。。。弱弱问句:怎么用挖。。。 :idea:

    • QiQiBoY --#1

      @Afio
      我讲的已经够详细了吧。。。另外我还提供了demo包,你可以下载下来查看。。

  4. 阿七 -#4

    好多重复。。。

  5. zwwooooo -#5

    华丽的读者墙

  6. mice -#6

    好吧 他们都说华丽..我说帅气吧` :!:

  7. 静夜燃香 -#7

    很美的效果诶~~~收藏~~等我决定折腾的时候再说~~~~最近没心情折腾了……

  8. BoKeam -#8

    我也觉得很华丽,我看能不能把它弄上去 :grin:

  9. BoKeam -#9

    不能下载了。。115都挂了 :shock:

  10. Dianso -#10

    读者墙都做得这么华丽,我还排在第二行呢

  11. 微奇生活 -#11

    主题好棒噢

  12. 枫雪 -#12

    可惜不用WP..哎…

    • QiQiBoY --#1

      @枫雪
      这个和博客程序版本无关。我这里给出的只是前端的js代码,只要你能输出所要求的页面html结构就可以使用,任意博客都行。。

  13. winy -#13

    他们都说华丽,那我可以说js好复杂么。。。 :roll:

  14. 宿迁学院论坛 -#14

    我也有读者墙 但你这个貌似更强大一些啊~

  15. 学夫子 -#15

    我也用上emlog的读者墙了,不过我没有要头像,直接显示名字,为了提高博客的速度

  16. 阿修 -#16

    挺好看,不过我还没放读者墙

  17. snowxh -#17

    不看js看墙都觉得好复杂- -

  18. 卢松松 -#18

    js加载的好慢。不过看的出博主确实有点功底

  19. QiQiBoY -#19

    消灭44

  20. 学夫子 -#20

    我也有读者墙的,我的是只显示名字没有头像

  1. Hello WordPress!

    [...] 进入九月份,我无聊的几天便折腾了个读者墙,于是有了这两篇我的读者墙展示(附所用JS代码)、读者墙效果【二】- [...]

  2. 【JS温故知新】之——给力的鼠标坐标位置获取

    [...] 至于DEMO嘛,我就不专门给出了。我在之前的博文我的读者墙展示(附所用JS代码)和读者墙效果【二】- 头像自由拖拽两篇文章中都用到了鼠标坐标获取,demo可以参看这两篇文章中的例子。其中我的读者墙展示(附所用JS代码)一文中在获取页面宽度时也考虑了标准模式和怪癖模式,有兴趣可以在那篇文章的代码中找找相关代码所在。 [...]

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: