OSChina “你也许会喜欢” 的实现

虫虫 发布于 2012/02/22 20:34
阅读 2K+
收藏 92

点击OSChina的任意一篇新闻,当滚动条滚动到页面下方的时候,右下角会以抽屉动画的形式显示一个框,里面列出了跟这篇新闻相关的其他新闻。看到有人问这个功能如何实现的,特此分享。

原理:

指定一个页面元素为标记,比如一个按钮,或者一个DIV,当此标记元素在页面上出现的时候就触发抽屉动画的事件。动画的效果是由jQuery的animate方法实现的。这个动画会把一个原本隐藏的DIV以抽屉的形式展现在页面上。当用户向上滚动页面,标记元素被移出屏幕的时候,触发事件把之前显示出来的DIV以抽屉动画的形式隐藏。很简单吧!

实现步骤:

1. 指定标记元素

通常情况下,当用户看到OSC的新闻页面“网友评论”这个版块的时候,说明用户已经看完了当前新闻,那么这个时候,弹出一个框显示其他类似的新闻就能引起用户的兴趣。所以我们指定“网友评论”这个DIV为标记元素:

<div class="Comments" id="userComments" >

这里并没有什么特殊的代码。这个元素的id是要被JS调用的。

2. 指定要弹出的 DIV

“你也许会喜欢”这个框一直在页面上的,只不过是隐藏了:

<div id="upprev_box" class="lbox HomeHotNews"  style="position: fixed; bottom:0; right:-400px; width:380px; height:100px;background-color:#FFFFFF;">
        		<strong>你也许会喜欢</strong>
        		<ul class='SimpleNewsList'>#foreach($n in $News.LoadList($r_news))#if($velocityCount <= 3) <li><a href="$n.iurl()" title="$format.html(${n.title})">$format.html($format.abbreviate(${n.title},30))</a><span class='date'>$date.friendly_time($request,${n.create_time})</span></li>#end#end<div class='clear'></div></ul>
        		<div class='clear'></div>
        	</div>

3. 处理窗口滚动事件

这里就用代码注释来解释了:

// 这个方法是用来计算滚动条的Y坐标的,我也是从别的地方COPY过来的 :)
function getScrollY() {
    scrOfY = 0;
    if( typeof( window.pageYOffset ) == "number" ) {
        scrOfY = window.pageYOffset;
    } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
        scrOfY = document.body.scrollTop;
    } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
        scrOfY = document.documentElement.scrollTop;
    }
    return scrOfY;
}

jQuery(function($){
    var upprev_closed = false; // 这个变量记录了弹出框是否被用户主动关闭,OSC没有实现这个功能,没有做弹出框的关闭按钮。
    var upprev_hidden = true; // 这个变量记录了弹出框的状态是否是隐藏的。
    // 监听窗口的滚动事件
    $(window).scroll(function() {
        var lastScreen; // 这个变量用来记录是否到达了该显示弹出框的屏幕位置
        if ($("#userComments").length > 0)
            lastScreen = getScrollY() + $(window).height() < $("#userComments").offset().top * 1 ? false : true;
        else
            lastScreen = getScrollY() + $(window).height() < $(document).height() * 1 ? false : true;
        // 如果 lastScreen 为 true,也就是用户向下滚动到标记元素,并且用户没有主动关闭过弹出框,那么弹出指定的DIV
        if (lastScreen && !upprev_closed) {
            $("#upprev_box").stop().animate({right:"0px"});
            upprev_hidden = false;
        }
        else if (upprev_closed && getScrollY() == 0) {
            upprev_closed = false;
        }
        // 当 lastScreen 为 false,也就是用户向上滚动到标记元素,那么隐藏指定的DIV
        else if (!upprev_hidden) {
            upprev_hidden = true;
            $("#upprev_box").stop().animate({right:"-400px"});
        }
    });
    // 用户主动关闭弹出框
    $("#upprev_close").click(function() {
        $("#upprev_box").stop().animate({right:"-400px"});
        upprev_closed = true;
        upprev_hidden = true;
    });
}); 

加载中
1
mark35
mark35

优化下性能:

jQuery(document).ready(function($){
    var upprev_closed = false; // 这个变量记录了弹出框是否被用户主动关闭,OSC没有实现这个功能,没有做弹出框的关闭按钮。
    var upprev_hidden = true; // 这个变量记录了弹出框的状态是否是隐藏的。
    var elm_ucomt = $('#userComments'),
        elm_ubox = $('#upprev_box'),
        elm_doc = $(this);
    // 监听窗口的滚动事件
    $(window).scroll(function() {
        var winheight = getScrollY() + $(this).height();        
        var lastScreen = elm_ucomt.length > 0 
                     ? (winheight < elm_ucomt.offset().top * 1 ? false : true)
                     : (winheight < elm_doc.height() * 1 ? false : true);

        // 如果 lastScreen 为 true,也就是用户向下滚动到标记元素,并且用户没有主动关闭过弹出框,那么弹出指定的DIV
        if (lastScreen && !upprev_closed) {
            elm_ubox.stop().animate({right:"0px"});
            upprev_hidden = false;
        }
        else if (upprev_closed && getScrollY() == 0) {
            upprev_closed = false;
        }
        // 当 lastScreen 为 false,也就是用户向上滚动到标记元素,那么隐藏指定的DIV
        else if (!upprev_hidden) {
            upprev_hidden = true;
            elm_ubox.stop().animate({right:"-400px"});
        }
    });
    // 用户主动关闭弹出框
    $("#upprev_close").click(function() {
        elm_ubox.stop().animate({right:"-400px"});
        upprev_closed = true;
        upprev_hidden = true;
    });
}); 

 

 

 

0
英强
英强
soga,又学到东西了!
0
rigger
rigger
果断加入到收藏,牛x!
0
FoxHu
FoxHu
学习了!
0
IdleMan
IdleMan

是按分类或者tag进行筛选内容的;

还是根据用户阅读习惯(类似豆瓣的)得出的筛选内容;

亦或者对新闻内容进行关键词抽取然后到索引库中查找匹配关键词的文章?

 

 

IdleMan
IdleMan
@红薯 : 恩。后台实现也想了解了解哦,呵呵。
红薯
红薯
这里讲的是抽屉效果的实现方式:)
0
光翟

IE6下有问题

0
cat_l_fish
cat_l_fish
还真是开源中国啊, 不错…… 昨天我还想这个问题呢,哈哈
0
羽殇墨
羽殇墨
牛X!学习...
0
润根
润根
很不错,又学习到东西了,赞一个。。
返回顶部
顶部