JS及JQ实现瀑布流

一、JS

  1 <!Doctype html>
  2 <html>
  3  <head>
  4     <title>瀑布流布局</title>
  5     <meta charset="utf-8" />
  6     <style>
  7         * {
  8             margin: 0;
  9             padding: 0;
 10         }
 11 
 12         #main {
 13             position: relative;
 14             margin: 0 auto;
 15         }
 16 
 17         .box {
 18             float: left;
 19             padding: 5px;
 20         }
 21 
 22         .pic {
 23             padding: 10px;
 24             border: 1px solid #CCC;
 25             border-radius: 5px;
 26             box-shadow: 0 0 5px #CCC;
 27         }
 28 
 29         .pic img {
 30             display: block;
 31             width: 200px;
 32         }
 33     </style>
 34     <script>
 35         var picData = {
 36             "data":
 37             [{"src":"http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD"},
 38             {"src":"http://img.hb.aicdn.com/78bc1f7341492a1dc6d70650b92a036d3e3bb21028fb5d-vH2TzM"},
 39             {"src":"http://img.hb.aicdn.com/09acb356a3a0a5617e929729b72bc0fb3ab8502d17e76e-bqWSl2"},
 40             {"src":"http://img.hb.aicdn.com/9924f421b5f2088c29555ed75901743b797aa17b1249a8-Up4UnF"},
 41             {"src":"http://img.hb.aicdn.com/3cb0a679eafb6a65551ef0a9647ad2195cb16d0813bf7c-c3jnPO"}]
 42         }
 43 
 44         var heightArr = [];
 45 
 46         window.onload=function(){
 47             waterfall('main','box');
 48             window.onscroll = function(){
 49                 addPic();
 50            }
 51         }
 52 
 53         function waterfall(parent,box){
 54             var oParent=document.getElementById(parent);
 55             var oBoxs=getByClass(oParent,box);
 56             var clientWidth = document.documentElement.clientWidth || document.body.clientWidth;
 57             var cols = Math.floor(clientWidth/oBoxs[0].offsetWidth);
 58             document.getElementById('main').style.width = oBoxs[0].offsetWidth * cols + 'px';
 59             for(var i=0;i<oBoxs.length;i++){
 60                 if(i<cols){
 61                     // 将图片的高度值添加到数组中
 62                     heightArr.push(oBoxs[i].offsetHeight);
 63                 }else{
 64                     // 求最小值和最小值的索引
 65                     var minHeight = Math.min.apply(null,heightArr);
 66                     var minhindex = getMinhIndex(heightArr,minHeight);
 67                     // 计算及定义图片出现的位置
 68                     oBoxs[i].style.position='absolute';
 69                     oBoxs[i].style.left = oBoxs[i].offsetWidth * minhindex + 'px';
 70                     oBoxs[i].style.top = minHeight + 'px';
 71                     // 改变数组值
 72                     heightArr[minhindex] += oBoxs[i].offsetHeight;
 73                 }
 74             }
 75         }
 76 
 77         function getByClass(parent,clsName){
 78             var boxArr=new Array(), 
 79             oElements=parent.getElementsByTagName('*');
 80             for(var i=0;i<oElements.length;i++){
 81                 if(oElements[i].className.indexOf(clsName)>=0){
 82                     boxArr.push(oElements[i]);
 83                 }
 84             }
 85             return boxArr;
 86         }
 87 
 88         // 求值在数组中的索引,arr接收的是数组,val接收的是判断的值
 89         function getMinhIndex(arr,val){
 90             for(var j in arr){
 91                 if(arr[j] == val){
 92                     return j;
 93                 }
 94             }
 95         }
 96 
 97         function addPic(){
 98             var sclh = document.documentElement.scrollHeight || document.body.scrollHeight;
 99             var sclt = document.documentElement.scrollTop || document.body.scrollTop;
100             var clth = document.documentElement.clientHeight || document.body.clientHeight;
101             if(sclt + clth > sclh-100){
102                 for(var i = 0; i < picData.data.length; i++){
103                     var newBox = document.createElement('div');
104                     newBox.className = 'box';
105                     newBox.innerHTML = '<div class="pic"><img src=' + picData.data[i].src + ' /></div>';
106                     var maindiv = document.getElementById('main');
107                     maindiv.appendChild(newBox);
108                     var minHeight = Math.min.apply(null,heightArr);
109                     var minhindex = getMinhIndex(heightArr,minHeight);
110                     newBox.style.position='absolute';
111                     newBox.style.left = newBox.offsetWidth * minhindex + 'px';
112                     newBox.style.top = minHeight + 'px';
113                     heightArr[minhindex] += newBox.offsetHeight;
114                     console.log(heightArr);
115                 }
116             }
117         }
118     </script>
119  </head>
120  <body>
121      <div id="main">
122         <div class="box">
123             <div class="pic">
124                 <img src="http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD" />
125             </div>
126         </div>
127         <div class="box">
128             <div class="pic">
129                 <img src="http://img.hb.aicdn.com/78bc1f7341492a1dc6d70650b92a036d3e3bb21028fb5d-vH2TzM" />
130             </div>
131         </div>
132         <div class="box">
133             <div class="pic">
134                 <img src="http://img.hb.aicdn.com/09acb356a3a0a5617e929729b72bc0fb3ab8502d17e76e-bqWSl2" />
135             </div>
136         </div>
137         <div class="box">
138             <div class="pic">
139                 <img src="http://img.hb.aicdn.com/9924f421b5f2088c29555ed75901743b797aa17b1249a8-Up4UnF" />
140             </div>
141         </div> 
142         <div class="box">
143             <div class="pic">
144                 <img src="http://img.hb.aicdn.com/3cb0a679eafb6a65551ef0a9647ad2195cb16d0813bf7c-c3jnPO" />
145             </div>
146         </div>
147         <div class="box">
148             <div class="pic">
149                 <img src="http://img.hb.aicdn.com/594fc7a1bb9a540f77ab655c852fea0f6a2cb97e98794-arggdw" />
150             </div>
151         </div>
152         <div class="box">
153             <div class="pic">
154                 <img src="http://img.hb.aicdn.com/e00ef0b6fcb22d3fa80d448ed3386829f8588bccc4e49-bJALYb" />
155             </div>
156         </div>
157         <div class="box">
158             <div class="pic">
159                 <img src="http://img.hb.aicdn.com/c01937b87bb90b8b377ad5367e55b89b6a097f2d71ccf-l3s20V" />
160             </div>
161         </div>
162         <div class="box">
163             <div class="pic">
164                 <img src="http://img.hb.aicdn.com/97605ab1a977571b49b11419e8c0714873bff28a1ba611-16hUyu" />
165             </div>
166         </div>
167         <div class="box">
168             <div class="pic">
169                 <img src="http://img.hb.aicdn.com/ec854de31c2d2b80558e97b6c4eafaf8b78fba94173b46-hvBou0" />
170             </div>
171         </div>
172         <div class="box">
173             <div class="pic">
174                 <img src="http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD" />
175             </div>
176         </div>
177     </div>
178  </body>
179 </html>

二、JQ

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>瀑布流</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #main {
            position: relative;
            margin: 0 auto;
        }

        .box {
            float: left;
            padding: 5px;
        }

        .pic {
            padding: 10px;
            border: 1px solid #CCC;
            border-radius: 5px;
            box-shadow: 0 0 5px #CCC;
        }

        .pic img {
            display: block;
            width: 200px;
        }
    </style>
    <script src='http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js'></script>
    <script>
        var picData = {
            "data":
            [{"src":"http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD"},
            {"src":"http://img.hb.aicdn.com/78bc1f7341492a1dc6d70650b92a036d3e3bb21028fb5d-vH2TzM"},
            {"src":"http://img.hb.aicdn.com/09acb356a3a0a5617e929729b72bc0fb3ab8502d17e76e-bqWSl2"},
            {"src":"http://img.hb.aicdn.com/9924f421b5f2088c29555ed75901743b797aa17b1249a8-Up4UnF"},
            {"src":"http://img.hb.aicdn.com/3cb0a679eafb6a65551ef0a9647ad2195cb16d0813bf7c-c3jnPO"}]
        }

        var hArr = [];

        window.onload = function(){
            waterfloor();
            $(window).scroll(addPic);
        };

        function waterfloor(){
            //求列数,设main宽度
            var clientWidth = $(window).width();
            var boxWidth = $('#main>div').outerWidth();
            var cols = Math.floor(clientWidth/boxWidth);
            $('#main').width(boxWidth * cols);
            //排列图片
            var $boxes = $('#main>div');
            for(var i=0;i<$boxes.length;i++){
                if(i<cols){
                    hArr[i] = $boxes.eq(i).outerHeight();
                }else{
                    //获取最小高度及序列
                    var minH = Math.min.apply(null,hArr);
                    var minHindex = $.inArray(minH,hArr);
                    //设置图片位置
                    $boxes.eq(i).css({
                        'position' : 'absolute',
                        'left' : boxWidth * minHindex + 'px',
                        'top' : minH + 'px'
                    });
                    //更新高度
                    hArr[minHindex] += $boxes.eq(i).outerHeight();
                }
            }
        }

        function addPic(){
            if($(window).height()+$(window).scrollTop()>$(document).height()-200){
                for(var i=0;i<picData.data.length;i++){
                    //创建包含图片的盒子
                    var $picDiv = $('<div class="box"><div class="pic"><img></div></div>').appendTo($('#main'));
                    $($picDiv).find('img').attr('src',picData.data[i].src);
                    //获取最小高度及序列
                    var minH = Math.min.apply(null,hArr);
                    var minHindex = $.inArray(minH,hArr);
                    //设置图片位置
                    $picDiv.css({
                        'position' : 'absolute',
                        'left' : $picDiv.outerWidth() * minHindex + 'px',
                        'top' : minH + 'px'
                    });
                    //更新高度
                    hArr[minHindex] += $picDiv.outerHeight();
                }
            }
            console.log("窗口高:" + $(window).height());
            console.log('页面高:'+$(document).height());
            console.log(document.body.scrollHeight);
        }
    </script>
</head>
<body>
    <div id="main">
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD" />
           </div>
       </div>
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/78bc1f7341492a1dc6d70650b92a036d3e3bb21028fb5d-vH2TzM" />
           </div>
       </div>
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/09acb356a3a0a5617e929729b72bc0fb3ab8502d17e76e-bqWSl2" />
           </div>
       </div>
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/9924f421b5f2088c29555ed75901743b797aa17b1249a8-Up4UnF" />
           </div>
       </div> 
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/3cb0a679eafb6a65551ef0a9647ad2195cb16d0813bf7c-c3jnPO" />
           </div>
       </div>
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/594fc7a1bb9a540f77ab655c852fea0f6a2cb97e98794-arggdw" />
           </div>
       </div>
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/e00ef0b6fcb22d3fa80d448ed3386829f8588bccc4e49-bJALYb" />
           </div>
       </div>
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/c01937b87bb90b8b377ad5367e55b89b6a097f2d71ccf-l3s20V" />
           </div>
       </div>
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/97605ab1a977571b49b11419e8c0714873bff28a1ba611-16hUyu" />
           </div>
       </div>
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/ec854de31c2d2b80558e97b6c4eafaf8b78fba94173b46-hvBou0" />
           </div>
       </div>
       <div class="box">
           <div class="pic">
               <img src="http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD" />
           </div>
       </div>
   </div>
</body>
</html>

三、JQ实现带动画的瀑布流

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>带有分散效果的瀑布流</title>
<style type="text/css">
    * {
        padding: 0;
        margin: 0;
    }

    #main {
        position: relative;
        margin: 0 auto;
    }

    .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 {
        display: block;
        width:162px;
        height:auto;
    }
</style>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js"/></script>
<script>
    var hArr = []; 
    var dataInt = {
        "data":
        [{"src":"http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD"},
        {"src":"http://img.hb.aicdn.com/78bc1f7341492a1dc6d70650b92a036d3e3bb21028fb5d-vH2TzM"},
        {"src":"http://img.hb.aicdn.com/09acb356a3a0a5617e929729b72bc0fb3ab8502d17e76e-bqWSl2"},
        {"src":"http://img.hb.aicdn.com/9924f421b5f2088c29555ed75901743b797aa17b1249a8-Up4UnF"},
        {"src":"http://img.hb.aicdn.com/3cb0a679eafb6a65551ef0a9647ad2195cb16d0813bf7c-c3jnPO"}]
    };


    $( window ).on( "load", function(){
           // 调用waterfall函数
           waterfall();
        window.onscroll=function(){
               // 拖动滚动条时
               addpic();
         }
    });

    function waterfall(){
         // 计算及定位数据块显示分散效果
         // 计算列数并居中
         var clientWidth = $(window).width();
         var pinWidth = $('.pin').outerWidth();
         var cols = Math.floor(clientWidth/pinWidth);
         console.log(clientWidth,pinWidth,cols);
         $('#main').css('width',cols*pinWidth+'px');
         // 图片布局
         var $pins = $('.pin');
         for(var i=0;i<$pins.length;i++){
             if(i<cols){
                 hArr[i] = $pins.eq(i).outerHeight();
             }else{
                 $pins.eq(i).css('position','absolute');
                 // 求最低的图片及序号
                 var minH = Math.min.apply(null,hArr);
                 var minHindex = $.inArray(minH,hArr);
                 // 图片动画
                 $pins.eq(i).animate({
                     left : minHindex * pinWidth,
                     top : minH
                     },700);
                 hArr[minHindex] += $pins.eq(i).outerHeight();
             }
         }
     }

    function checkscrollside(){
          // 检测是否具备了加载数据块的条件
          var clientHeight = $(window).height();
          var sclHeight = $(window).scrollTop();
          var webHeight = $(document).height();
          if(clientHeight+sclHeight>webHeight-200){
              return true;
          }else{
              return false;
          }
    }

    function addpic(){
        if(checkscrollside()){
            for(var i=0;i<dataInt.data.length;i++){
                var $newDiv = $('<div class="pin"><div class="box"><img/></div></div>').appendTo($('#main'));
                $newDiv.find('img').attr('src',dataInt.data[i].src);
                console.log($newDiv.find('img').attr('src'));
                $newDiv.css('position','absolute');
                var minH = Math.min.apply(null,hArr);
                var minHindex = $.inArray(minH,hArr);
                $newDiv.animate({
                    left : minHindex * $newDiv.outerWidth(),
                    top : minH
                    },500);
                hArr[minHindex] += $newDiv.outerHeight();
            }
        }
    }

</script>
</head>
<body>
    <div id="main">
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/78bc1f7341492a1dc6d70650b92a036d3e3bb21028fb5d-vH2TzM" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/09acb356a3a0a5617e929729b72bc0fb3ab8502d17e76e-bqWSl2" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/9924f421b5f2088c29555ed75901743b797aa17b1249a8-Up4UnF" />
           </div>
       </div> 
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/3cb0a679eafb6a65551ef0a9647ad2195cb16d0813bf7c-c3jnPO" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/594fc7a1bb9a540f77ab655c852fea0f6a2cb97e98794-arggdw" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/e00ef0b6fcb22d3fa80d448ed3386829f8588bccc4e49-bJALYb" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/c01937b87bb90b8b377ad5367e55b89b6a097f2d71ccf-l3s20V" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/97605ab1a977571b49b11419e8c0714873bff28a1ba611-16hUyu" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/ec854de31c2d2b80558e97b6c4eafaf8b78fba94173b46-hvBou0" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/7b799ae8e52f22fe405601be1d57a62641e78ef989cbc-oB27nD" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/78bc1f7341492a1dc6d70650b92a036d3e3bb21028fb5d-vH2TzM" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/09acb356a3a0a5617e929729b72bc0fb3ab8502d17e76e-bqWSl2" />
           </div>
       </div>
       <div class="pin">
           <div class="box">
               <img src="http://img.hb.aicdn.com/9924f421b5f2088c29555ed75901743b797aa17b1249a8-Up4UnF" />
           </div>
       </div> 
   </div>
</body>
</html>

遇到的问题及注意事项:

1、JS中数组的indexOf方法兼容性不好,ie8不支持。

2、chrome不支持document.documentElement.scrollTop,应使用document.body.scrollTop||document.documentElement.scrollTop。

3、window.onload会在图片下载完成后生效,$(document).ready()不会等待图片下载。图片未下载完成时,获取图片高度会出现问题。

posted @ 2017-05-16 17:20  oliverlht  阅读(252)  评论(0编辑  收藏  举报