var $catalogueOffsetTop = $("aside#catalogue").offset().top;var $archiveOffestTop = $("aside#archive").offset().top;var $archiveOffestLeft = $("aside#archive").offset().left;$(window).bind("scroll resize",function(){// #right-area的跟随屏幕滚动效果if($("#right-area").height() <= $(window).height()){$("#right-area").stop(true,true).animate({"top": $(document).scrollTop() + "px"},800);}else if($("#right-area").height() > $(window).height() && $("#right-area").height() < $(document).height()){// 这段范围内是最关键的,允许滑动if(($(document).scrollTop() + $(window).height()) <= $("#right-area").height()){$("#right-area").stop(true,true).css("top","0");}else if(($(document).scrollTop() + $(window).height()) < $(document).height()){$right_top = $(document).scrollTop() + $(window).height() - $("#right-area").height();$("#right-area").stop(true,true).animate({"top": $right_top + "px"},800);}else{$right_top = $(document).height() - $("#right-area").height();$("#right-area").stop(true,true).css({"top": $right_top + "px"});//alert($(document).scrollTop() + $(window).height() - $(document).height());}}else if($("#right-area").height() >= $(document).height()){$("#right-area").height($(document).height()).stop(true,true).css({"overflow":"hidden","overflow-y":"scroll"});}if($(document).scrollLeft() == 0){ // 只有在屏幕处于左侧的时候才进行下面的跟随滚动,同时需要注意下面的if($(window).width() > 1024),是为了防止在小屏幕下还发生这种变化// aside#catalogue的上下滑动if($("aside#catalogue").outerHeight() < $(window).height()){if($(document).scrollTop() <= $catalogueOffsetTop){$("aside#catalogue").css({"position":"static","top":$catalogueOffsetTop});if($(window).width() > 1024)$("#main").css({"padding-left":"0"});}else{$("aside#catalogue").css({"position":"fixed","top":"0"});if($(window).width() > 1024)$("#main").css({"padding-left":$("aside#catalogue").outerWidth() + 5 + "px"});}}else if($("aside#catalogue").height() >= $(window).height() && $("aside#catalogue").outerHeight() < ($("footer").offset().top - $catalogueOffsetTop)){if(($(document).scrollTop() + $(window).height()) <= ($("aside#catalogue").outerHeight() + $catalogueOffsetTop)){$("aside#catalogue").css({"position":"static","top":$catalogueOffsetTop});if($(window).width() > 1024)$("#main").css({"padding-left":"0"});}else if(($(document).scrollTop() + $(window).height()) < $("footer").offset().top){$catalogue_top = $(window).height() - $("aside#catalogue").outerHeight() - 20;$("aside#catalogue").css({"position":"fixed","top": $catalogue_top + "px"});if($(window).width() > 1024)$("#main").css({"padding-left":$("aside#catalogue").outerWidth() + 5 + "px"});}else{$catalogue_top = $(window).height() - $("aside#catalogue").outerHeight() - 20 - ($(document).height() - $("footer").offset().top);$("aside#catalogue").css({"position":"fixed","top":$catalogue_top + "px"});if($(window).width() > 1024)$("#main").css({"padding-left":$("aside#catalogue").outerWidth() + 5 + "px"});}}// aside#archive的上下滑动if($("aside#archive").outerHeight() < $(window).height()){if($(document).scrollTop() <= $archiveOffestTop){$("aside#archive").css({"position":"static","top":$archiveOffestTop,"left":$archiveOffestLeft + "px"});}else{$("aside#archive").css({"position":"fixed","top":"0","left":$archiveOffestLeft + "px"});}}else if($("aside#archive").height() >= $(window).height() && $("aside#archive").outerHeight() < ($("footer").offset().top - $archiveOffestTop)){if(($(document).scrollTop() + $(window).height()) <= ($("aside#archive").outerHeight() + $archiveOffestTop)){$("aside#archive").css({"position":"static","top":$archiveOffestTop,"left":$archiveOffestLeft + "px"});}else if(($(document).scrollTop() + $(window).height()) < $("footer").offset().top){$catalogue_top = $(window).height() - $("aside#archive").outerHeight();$("aside#archive").css({"position":"fixed","top": $catalogue_top + "px","left":$archiveOffestLeft + "px"});}else{$catalogue_top = $(window).height() - $("aside#archive").outerHeight() - ($(document).height() - $("footer").offset().top);$("aside#archive").css({"position":"fixed","top":$catalogue_top + "px","left":$archiveOffestLeft + "px"});}}}else{ // 如果屏幕不处于左侧,就让这两个跟随归位$("aside#catalogue").css({"position":"static","top":$catalogueOffsetTop});$("#main").css({"padding-left":"0"});$("aside#archive").css({"position":"static","top":$archiveOffestTop,"left":$archiveOffestLeft + "px"});}}).scroll().resize();网络上有很多相关的代码,更有7行代码解决此问题的方法,甚至还有通用性的插件来实现此效果。然而它们都太过普遍化,对于不同的网站,特殊性不同,在一些细节上要做更多的考虑。
图一 跟随屏幕滚动逻辑设计图
从图一中我们来看一下这一设计思路。图中绿色部分为要跟随滚动的区域,灰色部分为整个网页,浅灰色部分为屏幕(能看到的区域)我们通过向下移动浅灰色的屏幕来模拟往下滚动滚动条。在①的阶段为初始阶段,这个时候网页一切照初始运作,没有任何动作。到②的阶段,屏幕向下滚动到一个临界点,即要跟随滚动区域的最低端。第③阶段是滚动过临界点之后,元素开始跟随屏幕滚动,我们可以看到,元素的底端和屏幕的底端对齐,元素的顶端已经看不到。第④个阶段的屏幕滚动到底部,可以想象,网页的底部是存在一些版权信息的,元素不能跟随滚到底部把这些信息遮住,因此在红线的地方就不再跟随滚动。
这是屏幕向下滚动的示意图,当屏幕向上滚动时,这是这个顺序的逆向。但是还有另外一个考虑,当屏幕在向上滚动时实现和向下滚动初始状的一种效果,即临界点是此时④中的绿色区域顶端,向上滚动时屏幕顶端和元素顶端对齐。出于技术难度的考虑,乌徒帮没有实现这一效果。
3、数和量的计算
在滚动时,我们要掌握好那些量是变化的,哪些又不变,在不变中找变,在变中找不变,总之要保持头脑清晰,分清如何去计算各种高度关系。
在图一中,我用了一条蓝色竖线来辅助高度计算,用红色的线指示屏幕和元素的位置,将蓝色竖线分成了a、b、c、d、e、f六段。那么他们之间有着哪些变化数量关系呢?(我们将绿色区域的元素定义为#myDiv,将版权信息在内的底部定义为#footer)
a+b+c+d+e+f=$(document).height();//文档高度,固定值a= $("#myDiv").offset().top;//#myDiv顶部到文档顶部的初始值,随着滚动,$("#myDiv").offset().top将会变化b=$("#myDiv").height();//元素的高度,固定值a+b+c=$(window).scrollTop()=$(docment).scrollTop();//滚动条的位置,即文档顶端到当前屏幕顶端的距离,不断变化中d=$(window).height();//屏幕的高度,固定值f=$("#footer").height();//#footer的高度,固定值a+b+c+d+e=$("#footer").offset().top=$(document).height()-$("#footer").height();//#footer顶部到文档顶部的距离,固定值,不过需要注意的是,$("#footer").offset().top+$("#footer").height()并非一定等于$(document).height(),你要看#footer下面是否已经没有了空白。在整个变化过程中,变化的值只有$(window).scrollTop()=$(docment).scrollTop()和$("#myDiv").offset().top,因此我们要抓住这些值之间的加减数量关系,做好逻辑判断和赋值。
var $catalogueOffsetTop = $("aside#catalogue").offset().top;var $archiveOffestTop = $("aside#archive").offset().top;var $archiveOffestLeft = $("aside#archive").offset().left;正是由于他们在scroll事件发生时会发生变化,因此要提前存放在变量中。
......}else if($("#right-area").height() >= ($("footer").offset().top + $("footer").height())){$("#right-area").height($("footer").offset().top + $("footer").height()).stop(true,true).css({"overflow":"hidden","overflow-y":"scroll"});}3、自己网页内特殊情况的变化