学习了某大神的瀑布流布局:
基本原理:(下图出自残手,请见谅它的不完美)
黑框:document
蓝色框:container容器
红色框:浏览器可视区域
黄线:A..offsetTop+Math.floor(A.offsetHeight/2)
绿线:document.documentElement.scrollTop
1.所有图片等宽不等长;
2.图片加载时机:当可视区域超过最后一张图片的1/2即可记载新内容:A..offsetTop+Math.floor(A.offsetHeight/2)>document.documentElement.scrollTop+document.documentElement.clientHeight
HTML+CSS
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 5 <link href='demo.css' type='text/css' rel='stylesheet'> 6 <script src='demo.js' type='text/javascript'></script> 7 <title瀑布流</title> 8 <style> 9 *{ 10 margin:0; 11 padding: 0; 12 } 13 #content{ 14 position: relative; 15 } 16 17 div.blc{ 18 19 padding: 15px 0 0 15px; 20 float: left; 21 } 22 div.pic{ 23 padding:10px; 24 border: 1px solid #ccc; 25 border-radius: 5px; 26 box-shadow: 0 0 5px #ccc; /*设置阴影,水平和垂直方向上偏移值为0,阴影模糊度为5px;*/ 27 } 28 .pic img{ 29 height: auto; 30 width: 236px; 31 } 32 33 </style> 34 </head> 35 <body> 36 <div id='content'> 37 <div class='blc'> 38 <div class='pic'><img src='images/1.jpg'></div> 39 </div> 40 <div class='blc'> 41 <div class='pic'><img src='images/2.jpg'></div> 42 </div> 43 <div class='blc'> 44 <div class='pic'><img src='images/3.jpg'></div> 45 </div> 46 <div class='blc'> 47 <div class='pic'><img src='images/4.jpg'></div> 48 </div> 49 <div class='blc'> 50 <div class='pic'><img src='images/5.jpg'></div> 51 </div> 52 <div class='blc'> 53 <div class='pic'><img src='images/6.jpg'></div> 54 </div> 55 <div class='blc'> 56 <div class='pic'><img src='images/7.jpg'></div> 57 </div> 58 <div class='blc'> 59 <div class='pic'><img src='images/8.jpg'></div> 60 </div> 61 <div class='blc'> 62 <div class='pic'><img src='images/9.jpg'></div> 63 </div> 64 <div class='blc'> 65 <div class='pic'><img src='images/10.jpg'></div> 66 </div> 67 <div class='blc'> 68 <div class='pic'><img src='images/11.jpg'></div> 69 </div> 70 <div class='blc'> 71 <div class='pic'><img src='images/12.jpg'></div> 72 </div> 73 <div class='blc'> 74 <div class='pic'><img src='images/13.jpg'></div> 75 </div> 76 <div class='blc'> 77 <div class='pic'><img src='images/14.jpg'></div> 78 </div> 79 <div class='blc'> 80 <div class='pic'><img src='images/15.jpg'></div> 81 </div> 82 <div class='blc'> 83 <div class='pic'><img src='images/16.jpg'></div> 84 </div> 85 <div class='blc'> 86 <div class='pic'><img src='images/17.jpg'></div> 87 </div> 88 <div class='blc'> 89 <div class='pic'><img src='images/18.jpg'></div> 90 </div> 91 <div class='blc'> 92 <div class='pic'><img src='images/19.jpg'></div> 93 </div> 94 <div class='blc'> 95 <div class='pic'><img src='images/20.jpg'></div> 96 </div> 97 <div class='blc'> 98 <div class='pic'><img src='images/21.jpg'></div> 99 </div> 100 <div class='blc'> 101 <div class='pic'><img src='images/22.jpg'></div> 102 </div> 103 <div class='blc'> 104 <div class='pic'><img src='images/23.jpg'></div> 105 </div> 106 <div class='blc'> 107 <div class='pic'><img src='images/24.jpg'></div> 108 </div> 109 <div class='blc'> 110 <div class='pic'><img src='images/25.jpg'></div> 111 </div> 112 <div class='blc'> 113 <div class='pic'><img src='images/26.jpg'></div> 114 </div> 115 <div class='blc'> 116 <div class='pic'><img src='images/27.jpg'></div> 117 </div> 118 <div class='blc'> 119 <div class='pic'><img src='images/31.jpg'></div> 120 </div> 121 <div class='blc'> 122 <div class='pic'><img src='images/29.jpg'></div> 123 </div> 124 <div class='blc'> 125 <div class='pic'><img src='images/30.jpg'></div> 126 </div> 127 </div> 128 </body> 129 </html>
JAVASCRIPT
window.onload=function(){ waterfall('content','blc'); //Json模仿后台数据 var dataInt={"data":[{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'},{"src":'4.jpg'},{"src":'5.jpg'},{"src":'6.jpg'},{"src":'7.jpg'},{"src":'8.jpg'},{"src":'9.jpg'},{"src":'10.jpg'}]} window.onscroll=function(){ if(checkScrollSlide){ //加载数据 var oparent=document.getElementById('content') for(var i=0; i<dataInt.data.length; i++){ var oblc=document.createElement('div') //创建模块div节点 oblc.className='blc'; oparent.appendChild(oblc); var opic=document.createElement('div') //创建图片外层div节点 opic.className='pic'; oblc.appendChild(opic) var oimg=document.createElement('img') //创建img节点 oimg.src="images/"+dataInt.data[i].src opic.appendChild(oimg) } waterfall('content','blc'); //新加载的图片块执行瀑布流操作 } } } //实现瀑布流的函数 function waterfall(parent,box){ //取出所有的class为blc的元素 var oparent=document.getElementById(parent); //参数不用加引号 var oblc=getClass(oparent,box); // console.log(oblc.length) //计算页面显示的列数 var oblcW=oblc[0].offsetWidth; //每个图片块的宽度 var cols=Math.floor(document.documentElement.clientWidth/oblcW) //列数=屏幕宽度/图片块宽度,需要向下取整 //设置content的宽度和居中,cssText可以集中设置样式 oparent.style.cssText='Width:'+oblcW*cols+'px;margin:0 auto' ; //创建一个存放美列高度的数组 var hArray=[]; for(i=0; i<oblc.length;i++){ if(i<cols){ //i<cols的元素都是第一列元素 hArray.push(oblc[i].offsetHeight) //储存每列的高,开始时是第一列每一张图片的高 }else{ //开始第二列 var minH=Math.min.apply(null,hArray) //找出最小列的高度,Math.min方法不能存放数组,只能存放一组数,所有用apply方法更改函数或方法中this的指向 var index=getminhIndex(hArray,minH); oblc[i].style.position='absolute'; oblc[i].style.top=minH+'px'; //将高度设为最短列的高度 oblc[i].style.left=oblc[index].offsetLeft+'px'; hArray[index]+=oblc[i].offsetHeight; //每一列添加一个新元素后,该列高度=原来高度+新元素高度 } } } //根据className获取元素 function getClass(parent,clsName){ var classArray=[]; //用来储存取到的className元素 var allElements=parent.getElementsByTagName('*'); for(i=0;i<allElements.length;i++){ if(allElements[i].className==clsName){ classArray.push(allElements[i]) } } return classArray; } //取列高最小的列的索引 function getminhIndex(arr,val){ //传递俩个参数,一个是列高数组,一个是列高最小值 for(var i in arr){ if(arr[i]==val){ //返回列高最小值在数组中的索引,即列位 return i; } } } //是否加载的判断函数 function checkScrollSlide(){ var oparent=document.getElementById('content'); var oblc=getClass(oparent,'blc'); //加载条件:最后一个图像块的的offsetTop+自身高度的一半 < 滚动条的滚动量+屏幕的可视高度 var lastblcH=oblc[oblc.length-1].offsetTop+Math.floor(oblc[oblc.length-1].offsetHeight/2); var scrollTop=document.body.scrollTop ||document.documentElement.scrollTop; //混杂模式、标准模式;兼容 var height=document.body.clientHeight||document.documentElement.clientHeight; //浏览器可视区域 return (lastblcH<scrollTop+height)?true:false; }
jQuery实现:
$(window).on('load',function(){ waterfall('content','blc'); var dataInt={"data":[{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'},{"src":'4.jpg'},{"src":'5.jpg'},{"src":'6.jpg'},{"src":'7.jpg'},{"src":'8.jpg'},{"src":'9.jpg'},{"src":'10.jpg'}]} $(window).on('scroll',function(){ if(checkScrollSlide){ $.each(dataInt.data,function(key,value){ var obox=$('<div>').addClass('blc').appendTo($('#content')); var opic=$('<div>').addClass('pic').appendTo($(obox)); //这里value为js原生对象,无法使用jQuery方法,要转化为jQuery方法 var oimg=$('<img>').attr('src','images/'+$(value).attr('src')).appendTo($(opic)); //console.log(oimg.attr('src')) //console.log($(value).attr('src')) //console.log(value); }) waterfall(); } }) }) function waterfall(parent,box){ var oparent = $('#content'); var boxs = $('div .blc'); //计算列数 var boxW = boxs.eq(0).outerWidth(); var h = boxs.eq(0).outerHeight(); var clientW = $(window).width(); var lists = Math.floor(clientW/boxW); $('#content').width(lists*boxW).css('margin','0 auto'); //遍历,取出列高 var hArray=[]; boxs.each(function(index,value){ var h = boxs.eq(index).outerHeight(); //console.log(h) if(index<lists){ hArray[index]=h //console.log(hArray) }else{ var minH = Math.min.apply(null,hArray); var minHindex = $.inArray(minH,hArray); //获取数组索引值,第一个参数为值,第二个参数为数组名 //console.log(value) value为DOM对象,无法使用jQuery方法,要转化为jQuery方法 $(value).css({ 'position':'absolute', 'left':minHindex*boxW+'px', 'top':minH+'px' }) hArray[minHindex]+=boxs.eq(index).outerHeight(); } }) //console.log(hArray) } function checkScrollSlide(){ var lastblc = $('div .blc').last(); var lastblcH = lastblc.offset().top+Math.floor(lastblc.outerHeight()/2); console.log(lastblcH) var scrollTop = $(window).scrollTop(); var clientH = $(window).height(); return (lastblcH<scrollTop+clientH)?true:false; }