瀑布流效果可谓是2012年互联网上非常流行的一种效果,像蘑菇街,拖拉网这种网站更是通篇的瀑布流。美丽说,花瓣等也都在用. 顺应潮流,作者在这里也和大家分享一个瀑布流效果,先贴下瀑布流效果图: 9 v) j1 l$ \+ B# X* U
. v) N0 h, i/ l% _! f6 z
8 e: v) [* n8 ?6 O2 V8 g7 d- z5 c! P方法一,js实现瀑布流排序$ J+ S* g1 c, D
- <!DOCTYPE html >
- <html>
- <head>
- <meta charset="utf-8" />
- <title>js实现瀑布流排序</title>
- <style type="text/css">
- *{ margin:0; padding:0;}
- body { font:12px/1.8 Arial; color:#666;}
- h1.tit-h1 { font-size:38px; text-align:center; margin:30px 0 15px; color:#f60;}
- .go-back{ text-align:center; border-top:1px dashed #ccc; padding:10px; margin-top:20px; font-size:40px;}
- li{ list-style:none;}
- .wrapper {padding:50px;}
- </style>
- <link href="style.css" rel="stylesheet" type="text/css" />
- <body>
- <div class="wrapper">
- <div id="wrap" class="wrap active">
- <script language="javascript">
- var $id = function(o){ return document.getElementById(o) || o};
- for(i=0;i<30;i++){
- var src = Math.floor(Math.random()*100);
- if(src<10){src="0"+src}
- if(src<100){src="0"+src}
- var div = document.createElement("div");
- div.className = "mode popup_in";
- div.innerHTML = "<p class='pic'><a href='#'><img src=/notfound.jpg style='height:"+"auto"+";'/></a></p><h3 class='tit'><span><a href='#'>"+src+".jpg</a></span></h3>";
- div.style.top = 0;
- div.style.left = 0;
- document.getElementById("wrap").appendChild(div);
- }
- </script>
- </div>
- <script type="text/javascript">
- var warpWidth = 220; //格子宽度
- var margin = 14; //格子间距
- function postPosition(el,childTagName){
- var h = []; //记录每列的高度
- var box = el.getElementsByTagName(childTagName);
- var minH = box[0].offsetHeight,
- boxW = box[0].offsetWidth+margin;
- n = document.documentElement.offsetWidth / boxW | 0; //计算页面能排下多少Pin
- el.style.width = n * boxW - margin + "px";
- el.style.visibility = "visible";
- for(var i = 0; i < box.length; i++) {//排序算法,有待完善
- boxh = box[i].offsetHeight; //获取每个Pin的高度
- if(i < n) { //第一行特殊处理
- h[i] = boxh;
- box[i].style.top = 0 + 'px';
- box[i].style.left = (i * boxW) + 'px';
- }
- else {
- minH = Array.min(h); //取得各列累计高度最低的一列
- minKey = getarraykey(h, minH);
- h[minKey] += boxh+margin ; //加上新高度后更新高度值
- el.style.height = h[minKey] +"px";
- box[i].style.top = minH+margin + 'px';
- box[i].style.left = (minKey * boxW) + 'px';
- }
- }
- for(var i = 0; i < box.length; i++) {
- box[i].style.visibility = "visible"; //定位完毕后显示新增节点
- }
- }
- Array.min=function(array)
- {
- return Math.min.apply(Math,array);
- }
- /* 返回数组中某一值的对应项数 */
- function getarraykey(s, v) {
- for(k in s) {
- if(s[k] == v) {
- return k;
- }
- }
- }
- window.onload = function() {
- postPosition($id("wrap"),"div");
- };
- var re;
- window.onresize = function() {
- clearTimeout(re);
- re = setTimeout(resize,100);
- };
- function resize(){
- $id("wrap").className = "wrap active";
- postPosition($id("wrap"),"div");
- }
- </script>
- <div id="aaa1" style="display:none;position: fixed;width:400px;height:200px;background:#000;color:#fff;top:30%;left:50%"></div>
- </div>
- </body>
- </html>
复制代码
2 ^" B% E7 Y' N7 j/ b( R5 C Z+ Z" p
" Y' x; y, P j
4 L0 O3 o2 ?* b( D- G
实例二,js基于多栏列表瀑布流布局! O4 ]) x" i+ J
- <!DOCTYPE html >
- <html>
- <head>
- <meta charset="utf-8" />
- <title>js基于多栏列表瀑布流布局demo</title>
- <style type="text/css">
- *{ margin:0; padding:0;}
- body { font:12px/1.8 Arial; color:#666;}
- h1.tit-h1 { font-size:38px; text-align:center; margin:30px 0 15px; color:#f60;}
- .go-back{ text-align:center; border-top:1px dashed #ccc; padding:10px; margin-top:20px; font-size:40px;}
- li{ list-style:none;}
- .wrapper {padding:50px;}
- </style>
- <style>
- body {
- background-color: #eee;
- font-size: 84%;
- text-align: justify;
- }
- .column {
- display: inline-block;
- vertical-align: top;
- }
- .pic_a {
- display: block;
- padding: 5px;
- margin-bottom: 10px;
- border: 1px solid #ccc;
- background-color: #fff;
- text-decoration: none;
- }
- .pic_a img {
- display: block;
- margin: 0 auto 5px;
- border: 0;
- vertical-align: bottom;
- }
- .pic_a strong {
- color: #333;
- }
- </style>
- <body>
- <div class="wrapper">
- <div id="container"></div>
- <script>
- var waterFall = {
- container: document.getElementById("container"),
- columnNumber: 1,
- columnWidth: 210,
- // P_001.jpg ~ P_160.jpg
- rootImage: "http://cued.xunlei.com/demos/publ/img/",
- indexImage: 0,
-
- scrollTop: document.documentElement.scrollTop || document.body.scrollTop,
- detectLeft: 0,
-
- loadFinish: false,
-
- // 返回固定格式的图片名
- getIndex: function() {
- var index = this.indexImage;
- if (index < 10) {
- index = "00" + index;
- } else if (index < 100) {
- index = "0" + index;
- }
- return index;
- },
-
- // 是否滚动载入的检测
- appendDetect: function() {
- var start = 0;
- for (start; start < this.columnNumber; start++) {
- var eleColumn = document.getElementById("waterFallColumn_" + start);
- if (eleColumn && !this.loadFinish) {
- if (eleColumn.offsetTop + eleColumn.clientHeight < this.scrollTop + (window.innerHeight || document.documentElement.clientHeight)) {
- this.append(eleColumn);
- }
- }
- }
-
- return this;
- },
-
- // 滚动载入
- append: function(column) {
- this.indexImage += 1;
- var html = '', index = this.getIndex(), imgUrl = this.rootImage + "P_" + index + ".jpg";
-
- // 图片尺寸
- var aEle = document.createElement("a");
- aEle.href = "###";
- aEle.className = "pic_a";
- aEle.innerHTML = '<img src="'+ imgUrl +'" /><strong>'+ index +'</strong>';
- column.appendChild(aEle);
-
- if (index >= 160) {
- //alert("图片加载光光了!");
- this.loadFinish = true;
- }
-
- return this;
- },
-
- // 页面加载初始创建
- create: function() {
- this.columnNumber = Math.floor(document.body.clientWidth / this.columnWidth);
-
- var start = 0, htmlColumn = '', self = this;
- for (start; start < this.columnNumber; start+=1) {
- htmlColumn = htmlColumn + '<span id="waterFallColumn_'+ start +'" class="column" style="width:'+ this.columnWidth +'px;">'+
- function() {
- var html = '', i = 0;
- for (i=0; i<5; i+=1) {
- self.indexImage = start + self.columnNumber * i;
- var index = self.getIndex();
- html = html + '<a href="###" class="pic_a"><img src="'+ self.rootImage + "P_" + index +'.jpg" /><strong>'+ index +'</strong></a>';
- }
- return html;
- }() +
- '</span> ';
- }
- htmlColumn += '<span id="waterFallDetect" class="column" style="width:'+ this.columnWidth +'px;"></span>';
-
- this.container.innerHTML = htmlColumn;
-
- this.detectLeft = document.getElementById("waterFallDetect").offsetLeft;
- return this;
- },
-
- refresh: function() {
- var arrHtml = [], arrTemp = [], htmlAll = '', start = 0, maxLength = 0;
- for (start; start < this.columnNumber; start+=1) {
- var arrColumn = document.getElementById("waterFallColumn_" + start).innerHTML.match(/<a(?:.|n|r|s)*?a>/gi);
- if (arrColumn) {
- maxLength = Math.max(maxLength, arrColumn.length);
- // arrTemp是一个二维数组
- arrTemp.push(arrColumn);
- }
- }
-
- // 需要重新排序
- var lengthStart, arrStart;
- for (lengthStart = 0; lengthStart<maxLength; lengthStart++) {
- for (arrStart = 0; arrStart<this.columnNumber; arrStart++) {
- if (arrTemp[arrStart][lengthStart]) {
- arrHtml.push(arrTemp[arrStart][lengthStart]);
- }
- }
- }
-
-
- if (arrHtml && arrHtml.length !== 0) {
- // 新栏个数
- this.columnNumber = Math.floor(document.body.clientWidth / this.columnWidth);
-
- // 计算每列的行数
- // 向下取整
- var line = Math.floor(arrHtml.length / this.columnNumber);
-
- // 重新组装HTML
- var newStart = 0, htmlColumn = '', self = this;
- for (newStart; newStart < this.columnNumber; newStart+=1) {
- htmlColumn = htmlColumn + '<span id="waterFallColumn_'+ newStart +'" class="column" style="width:'+ this.columnWidth +'px;">'+
- function() {
- var html = '', i = 0;
- for (i=0; i<line; i+=1) {
- html += arrHtml[newStart + self.columnNumber * i];
- }
- // 是否补足余数
- html = html + (arrHtml[newStart + self.columnNumber * line] || '');
-
- return html;
- }() +
- '</span> ';
- }
- htmlColumn += '<span id="waterFallDetect" class="column" style="width:'+ this.columnWidth +'px;"></span>';
-
- this.container.innerHTML = htmlColumn;
-
- this.detectLeft = document.getElementById("waterFallDetect").offsetLeft;
-
- // 检测
- this.appendDetect();
- }
- return this;
- },
-
- // 滚动加载
- scroll: function() {
- var self = this;
- window.onscroll = function() {
- // 为提高性能,滚动前后距离大于100像素再处理
- var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
- if (!this.loadFinish && Math.abs(scrollTop - self.scrollTop) > 100) {
- self.scrollTop = scrollTop;
- self.appendDetect();
- }
-
- };
- return this;
- },
-
- // 浏览器窗口大小变换
- resize: function() {
- var self = this;
- window.onresize = function() {
- var eleDetect = document.getElementById("waterFallDetect"), detectLeft = eleDetect && eleDetect.offsetLeft;
- if (detectLeft && Math.abs(detectLeft - self.detectLeft) > 50) {
- // 检测标签偏移异常,认为布局要改变
- self.refresh();
- }
- };
- return this;
- },
- init: function() {
- if (this.container) {
- this.create().scroll().resize();
- }
- }
- };
- waterFall.init();
- </script>
- </div>
- </body>
- </html>
复制代码 5 m+ a r) ^; R0 x" m6 Y
' c1 v8 a$ R) W
参考:http://www.111cn.net/wy/js-ajax/52655.htm
5 D. p$ V- @9 L8 r( m2 z1 Q# f2 U c) G
/ T9 t% p$ O, g T3 J案例3:瀑布流布局——JS+绝对定位
# ?- {8 ^3 r( ^3 p* s, w9 ?& _2 l c
绝对定位方式的瀑布流布局: 一、布局 1、包围块框的容器: <div id="main"> ... ...<div>
! f8 `" m% z2 y. l1 l! j2、一个块框: <div class="pin"> <div class="box"> <img src="./images/g (1).jpg"/> </div></div>/ O& t! ?; L+ W7 t4 W
3、初始化第一行/5个块框: - .pin{
- padding: 15px 0 0 15px;
- float: left;}
- .box{
- padding: 10px;
- border:1px solid #ccc;}
- .box img{
- width:192px;
- height:auto;}
复制代码 4 H5 _$ Q8 t$ Y2 O/ I6 v6 s4 p2 {
' R: y- a8 k6 N3 z
效果: 8 L: ^7 C0 W' p3 j6 L; ?$ P
1 h/ D/ ?- _+ O0 J$ B
# ?) n9 y E; H2 D
二、思路: 1、设置父级main的样式:水平居中。9 c& T- x( ]5 O! f, ?5 n; n
2、设置每个块框pin的样式:绝对定位。' y$ x5 N! `9 l) F7 q3 T7 j( T
3、设置窗口滚动事件的监听函数:读取数据添加块框。 JS实现: 1-①:获取父级oParent:9 D# P& P( o9 r+ m: W7 f" G1 p N
1-②:创建函数getClassObj()-通过父级id和块框类名-获取包含块框的数组。 - var oParent=document.getElementById('main');// 父级对象
- var aPin=getClassObj(oParent,pin);// 获取存储块框pin的数组aPin
- var num=Math.floor(document.documentElement.clientWidth/aPin[0].offsetWidth);//获取-每行中能容纳的块框个数-num【窗口宽度除以一个块框宽度】
- oParent.style.cssText='width:'+iPinW*num+'px;margin:0 auto;';//用cssText属性为父级main添加居中样式:定宽+自动水平外边距
复制代码
) J- y5 _& ^: H& @
- function getClassObj(parent,className){
- var obj=parent.getElementsByTagName('*');//获取 父级的所有子集
- var pinS=[];//创建一个数组 用于存储类为className的元素
- for (var i=0;i<obj.length;i++) {//遍历子集、判断类名、压入数组
- if (obj[i].className==className)
- pinS.push(obj[i]);
- };
- return pinS;}
复制代码 / @4 ^3 f" ~% b
( {$ k' V; u' O' B) t% |& K; K! K( X: H
2-①:创建数组pinHArr-用于存储每一列高度;- w! D+ K' c/ K: F6 [
2-②:for语句遍历每个块框aPin,将前num个块框赋值给数组pinHArr,对超出一行能容纳的块框数num的块框绝对定位。+ a0 o+ F! U9 a: E* d. i
2-③:用创建函数getminHIndex()-返回一个数组中的最小值 - var pinHArr=[];//用于存储 每列中的所有块框相加的高度【随着列数的不同此数组的length也随之改变】
- for(var i=0;i<aPin.length;i++){//遍历数组aPin的每个块框元素
- var pinH=aPin[i].offsetHeight;//获取数组aPin的第i个块框的可见宽offsetHeight
- if(i<num){//
- pinHArr[i]=pinH; //第一行中的num个块框aPin 先添加进数组pinHArr
- }else{
- var minH=Math.min.apply(null,pinHArr);//计算数组pinHArr中的最小值minH
- var minHIndex=getminHIndex(pinHArr,minH);//通过创建的getminHIndex()-获取最小值minH在数组pinHArr中的索引minHIndex
- aPin[i].style.position='absolute';//设置绝对位移
- aPin[i].style.top=minH+'px';
- aPin[i].style.left=aPin[minHIndex].offsetLeft+'px';//数组 最小高元素的高 + 添加上的aPin[i]块框高
- pinHArr[minHIndex]+=aPin[i].offsetHeight;//更新添加块框后的列高
- }
- }
复制代码
+ a* T$ D* Q/ p `
- function getminHIndex(arr,minH){ for(var i in arr){
- if(arr[i]==minH)return i;
- }
- }
复制代码 , ?2 ?! G6 |8 R; B5 K
3:设置窗口滚动事件的监听函数:读取数据添加块框。 - var dataInt={'data':[{'src':'g (1).jpg'},{'src':'g (9).jpg'},{'src':'g (2).jpg'},{'src':'g (4).jpg'}]};//一个临时的数据对象
- //下面定义窗口滚动事件监听函数
- window.onscroll=function(){
- if(checkscrollside()){
- var oParent=document.getElementById('main');// 父级对象
- for(var i=0;i<dataInt.data.length;i++){
- var oPin=document.createElement('div'); //创建添加 元素节点pin
- oPin.className='pin'; //添加 类名 name属性
- oParent.appendChild(oPin); //创建添加 子节点box
- var oBox=document.createElement('div');
- oBox.className='box';
- oPin.appendChild(oBox);
- var oImg=document.createElement('img');//创建添加 子节点img
- oImg.src='./images/'+dataInt.data[i].src;
- oBox.appendChild(oImg);
- }
- waterfall('main','pin');//将①②封装成函数waterfall(),将添加的节点添加到添加和定位到文档中。
- };
- }
- function checkscrollside(){
- var oParent=document.getElementById('main');
- var aPin=getClassObj(oParent,'pin');
- var lastPinH=aPin[aPin.length-1].offsetTop+Math.floor(aPin[aPin.length-1].offsetHeight/2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
- var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//注意解决兼容性
- var documentH=document.documentElement.clientHeight;//窗口高度
- return (lastPinH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数
- }
复制代码 ' v* {3 G2 ?: o; R8 v/ O
三、最终效果: ( R5 S. V( |6 Z. P! d4 L6 X1 H
四、总结:此为让自己梳理一下思路,表达不太仔细连贯,仅供参考。
- U( J9 a6 }9 m8 B- Z) H
( s% K1 s. l* |; d* F
五、完成后的html文件和js文件: ' J t) T; I& ^( E; z
html:index.html - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="anchor" content="who care?" />
- <script type="text/javascript" src="waterfall.js"/></script>
- <title></title>
- <style type="text/css">
- *{padding: 0;margin:0;}
- #main{
- position: relative;
- }
- .pin{
- padding: 15px 0 0 15px;
- float:left;
- }
- .box{
- padding: 10px;
- border:1px solid #ccc;
- box-shadow: 0 0 6px #ccc;
- border-radius: 5px;
- }
- .box img{
- width:162px;
- height:auto;
- }
- </style>
- </head>
- <body>
- <div id="main">
- <div class="pin">
- <div class="box">
- <img src="./images/g (1).jpg"/>
- </div>
- </div>
- <div class="pin">
- <div class="box">
- <img src="./images/g (2).jpg"/>
- </div>
- </div>
- <div class="pin">
- <div class="box">
- <img src="./images/g (3).jpg"/>
- </div>
- </div>
- <div class="pin">
- <div class="box">
- <img src="./images/g (4).jpg"/>
- </div>
- </div>
- <div class="pin">
- <div class="box">
- <img src="./images/g (5).jpg"/>
- </div>
- </div>
- </div>
- </body>
- </html>
复制代码
5 L0 _3 R5 b8 J5 y. D3 o5 t# n% D
js:waterfall.js - window.onload=function(){
- waterfall('main','pin');
- var dataInt={'data':[{'src':'g (1).jpg'},{'src':'g (9).jpg'},{'src':'g (2).jpg'},{'src':'g (4).jpg'}]};
-
- window.onscroll=function(){
- if(checkscrollside()){
- var oParent=document.getElementById('main');// 父级对象
- for(var i=0;i<dataInt.data.length;i++){
- var oPin=document.createElement('div'); //添加 元素节点
- oPin.className='pin'; //添加 类名 name属性
- oParent.appendChild(oPin); //添加 子节点
- var oBox=document.createElement('div');
- oBox.className='box';
- oPin.appendChild(oBox);
- var oImg=document.createElement('img');
- oImg.src='./images/'+dataInt.data[i].src;
- oBox.appendChild(oImg);
- }
- waterfall('main','pin');
- };
- }
-
- }
- /*
- parend 父级id
- pin 元素id
- */
- function waterfall(parent,pin){
- var oParent=document.getElementById(parent);// 父级对象
- var aPin=getClassObj(oParent,pin);// 获取存储块框pin的数组aPin
- var iPinW=aPin[0].offsetWidth;// 一个块框pin的宽
- var num=Math.floor(document.documentElement.clientWidth/iPinW);//每行中能容纳的pin个数【窗口宽度除以一个块框宽度】
- oParent.style.cssText='width:'+iPinW*num+'px;ma rgin:0 auto;';//设置父级居中样式:定宽+自动水平外边距
- var pinHArr=[];//用于存储 每列中的所有块框相加的高度。
- for(var i=0;i<aPin.length;i++){//遍历数组aPin的每个块框元素
- var pinH=aPin[i].offsetHeight;
- if(i<num){
- pinHArr[i]=pinH; //第一行中的num个块框pin 先添加进数组pinHArr
- }else{
- var minH=Math.min.apply(null,pinHArr);//数组pinHArr中的最小值minH
- var minHIndex=getminHIndex(pinHArr,minH);
- aPin[i].style.position='absolute';//设置绝对位移
- aPin[i].style.top=minH+'px';
- aPin[i].style.left=aPin[minHIndex].offsetLeft+'px';
- //数组 最小高元素的高 + 添加上的aPin[i]块框高
- pinHArr[minHIndex]+=aPin[i].offsetHeight;//更新添加了块框后的列高
- }
- }
- }
- /****
- *通过父级和子元素的class类 获取该同类子元素的数组
- */
- function getClassObj(parent,className){
- var obj=parent.getElementsByTagName('*');//获取 父级的所有子集
- var pinS=[];//创建一个数组 用于收集子元素
- for (var i=0;i<obj.length;i++) {//遍历子元素、判断类别、压入数组
- if (obj[i].className==className){
- pinS.push(obj[i]);
- }
- };
- return pinS;
- }
- /****
- *获取 pin高度 最小值的索引index
- */
- function getminHIndex(arr,minH){
- for(var i in arr){
- if(arr[i]==minH){
- return i;
- }
- }
- }
- function checkscrollside(){
- var oParent=document.getElementById('main');
- var aPin=getClassObj(oParent,'pin');
- var lastPinH=aPin[aPin.length-1].offsetTop+Math.floor(aPin[aPin.length-1].offsetHeight/2);//创建【触发添加块框函数waterfall()】的高度:最后一个块框的距离网页顶部+自身高的一半(实现未滚到底就开始加载)
- var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;//注意解决兼容性
- var documentH=document.documentElement.clientHeight;//页面高度
- return (lastPinH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数
- }
复制代码
2 t' s4 g& q0 p2 A( J7 Y
% }. Y; X4 H4 ~ V2 z. \
/ {* f+ h- H) O& M查看更多参考:http://www.cnblogs.com/slowsoul/archive/2013/02/10/2909746.html
0 Y& o) x% V6 q6 \- E chttp://www.phpernote.com/php-template-framework/189.html5 v6 J; `# H g* N2 i, W# C7 y
www.baidu.com |