学习JS,活跃思维,灵活运用的一个较为典型的学习案例。同一个瀑布流的效果但实现方式却很多,利用递归、冒泡等等手法都可以达到你想要的目的。这次要说的就是利用类似递归来实现此效果的原创方案。此方案个人认为难度系数较低
1 <?php 2 //没有数据源,利用遍历对应文件夹中的所有的图片得到的数组模拟成数据源 3 $arr = array(); 4 $dir = @opendir('images'); 5 while($file = @readdir($dir)){ 6 if($file == '.' || $file == '..'){ 7 continue; 8 } 9 $arr[] = $file; 10 } 11 @closedir($dir); 12 ?> 13 <!DOCTYPE html> 14 <html> 15 <head> 16 <meta http-equiv="content-type" content="text/html; charset=utf-8"> 17 <title>瀑布流</title> 18 <style type="text/css"> 19 *{padding:0;margin:0} 20 .box{padding:5px;float:left;} 21 .image{padding:5px;border:1px solid #ccc;box-shadow: 0 0 5px #ccc;border-radius:5px;} 22 .image img{width:150px;height:auto;} 23 </style> 24 </head> 25 <body> 26 <div id="container" style=""> 27 <?php foreach($arr as $val):?> 28 <div class="box"> 29 <div class="image"> 30 <img src="images/<?php echo $val?>" /> 31 </div> 32 </div> 33 <?php endforeach;?> 34 </div> 35 </body> 36 <script> 37 window.onload = function(){ 38 imgLocation('container','box'); 39 } 40 window.onresize = function(){ 41 imgLocation('container','box'); 42 } 43 function imgLocation(parent,content){ 44 //取得大盒子的节点对象 45 var cparent = document.getElementById(parent); 46 //从大盒子中找到所有放图片的盒子 47 var ccontent = getChildElement(cparent,content); 48 //由于CSS已经规定所有Img的宽度为150,所以这边返回的图片盒子的宽度就是150+5*2+5*2+2 = 172; 49 var imgWidth = ccontent[0].offsetWidth; 50 //利用body体宽度和图片盒子所在宽度两者相除得到目前宽度下第一排能摆放的最大个数 51 var cols = Math.floor(document.documentElement.clientWidth / imgWidth); 52 //利用计算出来的一排最多的个数乘以每个图片的宽度得到大盒子应有的宽度 53 cparent.style.cssText = 'width:'+imgWidth*cols+'px;margin:0 auto;'; 54 console.log(cols); 55 //定义用于存放第一排图片盒子的高度所用的数组 56 var BoxHeightArr = []; 57 //循环遍历所有图片盒子 58 for(var i=0;i<ccontent.length;i++){ 59 //利用i的自增获取第一排所有盒子的高度(这里设计的很巧妙哦) 60 if(i<cols){ 61 //将第一排所有盒子的高度追加到之前定义的数组 62 BoxHeightArr[i] = ccontent[i].offsetHeight; 63 //并且把第一排盒子所有的绝对定位去掉,不然在实时拉伸窗口的时候会破坏自适应 64 ccontent[i].style.position = ''; 65 }else{ 66 //循环完第一排时利用取到的高度数组从中获取到最小高度 67 var minHeight = Math.min.apply(null,BoxHeightArr); 68 //自定义函数取得最小高度所在的盒子的位置(下标) 69 var minIndex = getminHeightLocation(BoxHeightArr,minHeight); 70 //修改第二排开始摆放的CSS,盒子定位修改成绝对定位,为后面的移动最准备 71 ccontent[i].style.position = 'absolute'; 72 //把当前循环盒子的Y坐标修改成最小盒子的高度(这样就可以让当前盒子排在第一排最小盒子的下面) 73 ccontent[i].style.top = minHeight + 'px'; 74 //把当前循环盒子的X坐标修改成最小盒子所在位置的X坐标(达到对齐效果) 75 ccontent[i].style.left = ccontent[minIndex].offsetLeft + 'px'; 76 //当本轮循环的修改操作全部完成后,更新第一排盒子高度的数组里的最小高度 77 //现在最小盒子的高度应该是之前的高度加上第二排追加上来的盒子的高度 78 //以此循环操作所有的盒子就能实现瀑布流的效果 79 BoxHeightArr[minIndex] = BoxHeightArr[minIndex]+ccontent[i].offsetHeight; 80 } 81 } 82 } 83 //以下开始是辅助部分,不一一赘述,上面是实现的核心,原理已经一一道明 84 function getChildElement(parent,content){ 85 var contentArr = []; 86 var allcontent = parent.getElementsByTagName('*'); 87 for(var i=0;i<allcontent.length;i++){ 88 if(allcontent[i].className == content){ 89 contentArr.push(allcontent[i]); 90 } 91 } 92 return contentArr; 93 } 94 95 function getminHeightLocation(BoxHeightArr,minHeight){ 96 for(var i=0;i<BoxHeightArr.length;i++){ 97 if(BoxHeightArr[i] == minHeight){ 98 return i; 99 } 100 } 101 102 } 103 104 </script> 105 </html>
效果展示: