瀑布流就是像瀑布一样的网站——丰富的网站内容,特别适应于图片。宽度固定,高度不固定。参差不齐的多栏布局。还可以响应式地适应不同大小的设备。
实现思路如下:
一.页面布局:一个装图片的div;一个装加载图片的div
二.js代码:
1.设置图片的宽度iWidth和图片间的间隙iSpace,列宽iOuterWidth=图片的宽度+图片间的间隙
2.列数iCells=获取的窗口大小/列宽
3.定义两个数组arrL和arrT来存储图片的位置,arrL存储图片left定位,arrT存储图片Top定位
4.初始化数组,确定第一行图片的定位
for(var i=0;i<iCells;i++){
arrT.push(0);
arrL.push(i*iOuterWidth);
}
5.根据定好的图片的宽度和图片宽高算出图片的高度
6.设置图片的宽高
7.获取页面中高度最小的列的索引值,把图片依次插入高度较小的列中。这样就完成了最简单的瀑布流局
三.性能优化的js代码:
1.图片的数据有时候是在一个URL中:如:http://www.wookmark.com/api/json/popular?callback=? 而庞大的数据通常是会分页的,这样可以一页页的加载数据,等一页数据加载完再加载下一页数据。所以js代码中要加判断条件,当滑动鼠标时触发函数判断是否需要加载下一页的数据
2.响应式设计:当窗口大小改变时,根据窗口大小重新算出列数,再重定位图片的位置即实现了响应式设计
代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,minimal-ui" /> <title>waterfall</title> <style type="text/css"> *{ margin: 0; padding: 0; } #container{ margin: 10px auto; position: relative; } #container img{ position: absolute; } #load{ width: 100%; height: 60px; background: url('loader.gif') no-repeat center #fff; position: fixed; bottom: 0; left: 0; } </style> <script type="text/javascript" src="jquery-1.9.1.min.js"></script> <script type="text/javascript"> $(function(){ var container=$('#container'); //放瀑布流图片的div var load=$('#load'); //放加载图片的div的类名 var sUrl = 'http://www.wookmark.com/api/json/popular?callback=?'; var iWidth=50; //单列的宽度 var iSpace=10; //间隔的宽度 var iOuterWidth=iWidth+iSpace; //实际列宽单列宽+间隔宽 var iCells=0; //初始化列数 var ipage=0; //初始化Json的页数 var iBtn=true; //设置一个参数,当参数为true时才执行函数,防止函数不断执行 var arrL=[]; //定位图片left的数组 var arrT=[]; //定位图片top的数组 //根据窗口的大小和列宽设置列数 function setCells(){ iCells=Math.floor($(window).innerWidth()/iOuterWidth); container.css('width',iOuterWidth*iCells-iSpace); } setCells(); //先初始化数组,确定第一行图片的定位 for(var i=0;i<iCells;i++){ arrT.push(0); arrL.push(i*iOuterWidth); } //获取一行中高度最小的列,返回该列的索引 function getMin(){ var iv=arrT[0]; var _index=0; for(var i=0;i<arrT.length;i++){ if(arrT[i]<iv){ iv=arrT[i]; _index=i; } } return _index; } //获取一行中高度最大的列,返回该列的索引 function getMax(){ var iv=arrT[0]; var _index=0; for(var i=0;i>arrT.length;i++){ if(arrT[i]<iv){ iv=arrT[i]; _index=i; } } return _index; } // 获取数据输出 function getData(){ if(iBtn){ iBtn=false; load.show();//显示加载图片 $.getJSON(sUrl,'page+=ipage',function(data){ $.each(data,function(index,obj){ //把图片显示在页面上 var oImg=$('<img />'); oImg.attr('src',obj.preview); container.append(oImg); //根据定好的图片的宽度和图片宽高算出图片的高度 var iHeight=iWidth/obj.width*obj.height; //设置图片的宽高 oImg.css({ width : iWidth, height : iHeight }) // 获取高度最小的列的索引值 var iMinIndex=getMin(); // 获取高度最高的列的索引值 var iMaxIndex=getMax(); //设置装图片的容器的高度 container.css('height',arrT[iMaxIndex]); // 定位图片的位置 oImg.css({ left : arrL[iMinIndex], top : arrT[iMinIndex] }); //上下图片间加10px的间隙 arrT[iMinIndex]+=iHeight+10; //一页的数据图片加载完成隐藏加载图片 load.hide(); iBtn=true; }) //使其一开始时就触发scroll事件来判断数据是否需要加载下一页 if(ipage<2){ $(window).trigger('scroll'); } }) } } getData(); //当滑动鼠标时触发函数判断是否需要加载下一页的数据 $(window).on('scroll',function(){ var iH=$(window).scrollTop()+$(window).innerHeight(); var iMinIndex=getMin(); if(arrT[iMinIndex]+container.offset().top<iH){ ipage++; getData(); } }); //当窗口大小改变时,重新调整图片。即响应式设计 $(window).on('resize', function() { var iLen = iCells; setCells(); if (iLen == iCells) { return ; } arrT = []; arrL = []; for (var i=0; i<iCells; i++) { arrT[i] = 0; arrL[i] = iOuterWidth * i; } container.find('img').each(function() { var _index = getMin(); /*$(this).css({ left : arrL[_index], top : arrT[_index] });*/ $(this).animate({ left : arrL[_index], top : arrT[_index] }, 1000); arrT[_index] += $(this).height() + 10; }); }) }) </script> </head> <body> <div id="container"></div> <div id="load"></div> </body> </html>