瀑布流效果可谓是2012年互联网上非常流行的一种效果,像蘑菇街,拖拉网这种网站更是通篇的瀑布流。美丽说,花瓣等也都在用. 顺应潮流,作者在这里也和大家分享一个瀑布流效果,先贴下瀑布流效果图:
. d/ G- p4 a3 }1 a" D9 r
9 Z5 y8 L( }' b9 O: K: P( Y- v& O$ o- J! ]0 V
方法一,js实现瀑布流排序. [. ^3 L2 V7 D& Y. X2 Q5 ]
- <!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>
复制代码 ' J; [7 r/ E9 W+ Q! z7 V. _
+ i- H* q4 K4 e% U/ E$ p, C- J# i9 o x8 g! y \
l5 i& D- h8 |, V实例二,js基于多栏列表瀑布流布局3 Y Q7 K3 x7 J4 x1 h; J) G7 S
- <!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 p" U a4 M0 j1 V9 _0 j U
- ^ j) W7 P: Y1 u( h参考:http://www.111cn.net/wy/js-ajax/52655.htm
/ B! ?. y- ]' p7 r* Z) s; [! D
$ z$ v; }5 b# }
$ s3 u, k4 D7 s' S5 h案例3:瀑布流布局——JS+绝对定位
7 }/ V' n4 j! G9 R/ n/ W) b0 X6 w0 [, ?% [/ E1 b" l
绝对定位方式的瀑布流布局: 一、布局 1、包围块框的容器: <div id="main"> ... ...<div>
6 l L2 z! S1 C' V2、一个块框: <div class="pin"> <div class="box"> <img src="./images/g (1).jpg"/> </div></div>* ~0 o( [# r7 t! v
3、初始化第一行/5个块框: - .pin{
- padding: 15px 0 0 15px;
- float: left;}
- .box{
- padding: 10px;
- border:1px solid #ccc;}
- .box img{
- width:192px;
- height:auto;}
复制代码 ) u' F0 @+ F' D% r+ v
' K$ P- w3 ^- U1 @* ^
效果:
& D1 j! }8 s8 z) Y7 F6 C
0 x1 E& @" u0 K3 Z. O / n* L. v. {9 S8 b
二、思路: 1、设置父级main的样式:水平居中。
1 t* ?- C v6 J9 [6 b4 e, C7 N2、设置每个块框pin的样式:绝对定位。! t) g# N D: w
3、设置窗口滚动事件的监听函数:读取数据添加块框。 JS实现: 1-①:获取父级oParent:
; R- w: M6 n0 F# x) t1 w/ U 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添加居中样式:定宽+自动水平外边距
复制代码 }% R) j6 e6 |% I
- 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;}
复制代码 }$ ]7 j2 S% C5 v& Q7 G
# @9 h) d* }0 \# ]% v7 Q- ]
2-①:创建数组pinHArr-用于存储每一列高度;
( t, B* e% @4 p' s' ^0 S- K 2-②:for语句遍历每个块框aPin,将前num个块框赋值给数组pinHArr,对超出一行能容纳的块框数num的块框绝对定位。
9 A6 D0 w) L! L' h: N 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;//更新添加块框后的列高
- }
- }
复制代码
: t: S- f- u/ t. ?& R" \6 p. M* _* t0 B
- function getminHIndex(arr,minH){ for(var i in arr){
- if(arr[i]==minH)return i;
- }
- }
复制代码
: f- x& b5 Z& `- ?2 _0 u3:设置窗口滚动事件的监听函数:读取数据添加块框。 - 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()函数
- }
复制代码
$ W* g: D' F# P
三、最终效果:
+ t. W* k, s- M; C$ f3 G 四、总结:此为让自己梳理一下思路,表达不太仔细连贯,仅供参考。
6 I& R/ C9 D H! i, \% A1 w! \
' Z. s9 k0 `# \* d
五、完成后的html文件和js文件:
* } @9 @. M; W9 t; c
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>
复制代码 4 _& M. Z! y; z. \, b1 g
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()函数
- }
复制代码 & J ]% ?0 f& o. G3 m8 `( ?& D
+ t3 s1 e6 i8 w6 k
% p4 V$ ]: e# _* w! }
查看更多参考:http://www.cnblogs.com/slowsoul/archive/2013/02/10/2909746.html1 p% k) V5 b. }3 r2 O( Y
http://www.phpernote.com/php-template-framework/189.html
~4 @" {$ s- R8 g4 {$ P# t2 xwww.baidu.com |