第一次在W3Cfuns上发表贴子,自己鼓励一下自己!

测试浏览器:Google Chrome V25.0
PS:本文不考虑浏览器兼容性,只讨论原理,有兴趣的同学也可以进行测试。

视差滚动/视觉差设计,这些词汇在现在看来是再平常不过了,虽平常,但是其牛X的效果不得不让用户眼前一亮,也让我们这些垒码的不得不思考其中的原理。

知识普及:视差滚动说白了就是多个元素以不同的层次堆叠在一起,并随鼠标滚轮滚动而进行位置移动,进而形成立体的运动效果。
也可以理解为N个元素堆叠的产物。具体我们可以用一张图来将其解剖。

<ignore_js_op>

视差滚动的背后_前端开发



如图,大多视差网站都是在这个模型的基础上去做效果。通常情况下,视差设计中都会在页面中形成一个指示导航,这样做的目的很显然就是能让用户清楚知道自己所处的位置,也能通过指示很快定位到自己想要去的位置;如此一来就可以得出一个结论,视差设计中是需要以区域来划分要展示的产物,从而给用户的操作有一个连贯性和渐进性。其实在浏览网上的一些视差网站时就会多少有感触。

那么说回上图,现在我们区域划分好了,接下来要做的自然就是体现他们的层级顺序:从上到下依次递减,如我这里有3个区域那么就是3-2-1(其实这里的顺序是不定的,主要是你想做成什么样,在这里只是举个例子)。剩下的就是需要计算每个区域距离顶部的top值。这个要怎么去计算,很简单,直接获取scrollTop的坐标位置就结了;我们可以先来看一个简单的示例,这个示例我称它为背景视差,因为涉及的是背景的定位,没有用到元素定位,所以这个很简单,你只要用CSS就能实现这一过程。

DEMO1

前面说只用CSS可以搞定,那DEMO1所涉及到的js其实是一个指示导航,可以暂先不理;这里最主要的实现体是css的background-attachment属性,这个属性在早期的版本就已经有了,只是在后来的CSS3版本中加入了一个新的取值(local),我们用得比较多的是fixed,其他的就可以暂时放一边,下面我们先了解一下该属性的取值:
=======================================================================
“<strong><attachment></strong> = fixed | local | scroll”

“fixed: 背景图像相对于窗体固定。”
“scroll: 背景图像相对于元素固定,也就是说当元素内容滚动时背景图像不会跟着滚动,因为背景图像总是要跟着元素本身。但会随元素的祖先元素或窗体一起滚动。”
“local: 背景图像相对于元素内容固定,也就是说当元素随元素滚动时背景图像也会跟着滚动,因为背景图像总是要跟着内容。(CSS3)”
=======================================================================

整个页面的大体结构如下:

  1. <div class="box box-1">
  2. 区域1
  3. </div>
  4. <div class="box box-2">
  5. 区域2
  6. </div>
  7. <div class="box box-3">
  8. 区域3
  9. </div>
复制代码

这里的box-1,2,3分别是三张背景图的类,这里需要注意的是背景视差的实现一定要把图片用于背景中,不能以img形式出现。在CSS中需要注意的是几个background的运用,这里就不多说了,爱折腾的同学可以复制源代码到本地捣鼓。

  1. .box{
  2.         position:relative;
  3.         height:939px; /* 此为元素背景图像实际高度 X 元素背景图像个数 */
  4.         margin:0 auto;
  5.         background-repeat:no-repeat;
  6.         background-position:center center;
  7.         background-attachment:fixed; /* 使背景图像相对于窗体固定 */
  8.         background-size:cover; /* 取值auto | cover | contain */
  9.         /* 背景图像的真实大小 */
  10.         /* 将背景图像等比缩放到完全覆盖容器,背景图像有可能超出容器 */
  11.         /* 将背景图像等比缩放到宽度或高度与容器的宽度或高度相等,背景图像始终被包含在容器内 */
  12.         overflow:hidden;
  13.         text-align:center;
  14. }
  15. .box-1{
  16.         background-image:url(images/p1.jpg);
  17. }
  18. .box-2{
  19.         background-image:url(images/p2.jpg);
  20. }
  21. .box-3{
  22.         background-image:url(images/p3.jpg);
  23. }
复制代码

接着着重讲一下行为方面的实现,因为在下集我们需要运用到这些东西,所以提前了解一下。
从这个指示导航开始吧,这东西是怎么实现的呢,其实很简单,前面讲了它的实现原理是需要通过划分区域来实现层级关系,这个指示导航就需要这个区域值来进行控制,总共我们有三个大区域,在滚动条进入到其中一个区域时触发条件成立,那么我们就可以在这个成立的基础上将指示点打到这个区域就可以了;看下代码就明了了

  1. <div class="slidecount">
  2.         <ul>
  3.                 <li class="focus"><a href="#n1">1</a></li>
  4.                 <li><a href="#n2">2</a></li>
  5.                 <li><a href="#n3">3</a></li>
  6.         </ul>
  7. </div><!-- 指示区 -->
复制代码
  1. $(function(){
  2.         var oWinTop;
  3.         var oBoxH = $(".box").height();
  4.         var vLen = 0;
  5.         var vIndex = [];
  6.         $(".slidecount li").each(function(){
  7.                 vLen = vLen + 1;
  8.                 vIndex.push($(this).index());
  9.         });
  10.         $(window).scroll(function(){
  11.                 oWinTop = $(window).scrollTop();
  12.                 /* 这里为区域划分 */
  13.                 if(oWinTop >= 0 && oWinTop < oBoxH){
  14.                         $(".slidecount li:eq("+vIndex[0]+")").addClass("focus").siblings("li").removeClass("focus");
  15.                 }else if(oWinTop >= oBoxH && oWinTop < (oBoxH * vIndex[2])){
  16.                         $(".slidecount li:eq("+vIndex[1]+")").addClass("focus").siblings("li").removeClass("focus");
  17.                 }else{
  18.                         $(".slidecount li:eq("+vIndex[2]+")").addClass("focus").siblings("li").removeClass("focus");
  19.                 }
  20.         });
  21. });
复制代码

JS不到位的地方,还请大神们指点,多谢
末尾分享个背景视差的完整版
DEMO