<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>瀑布流-jquery</title> <style> *{margin:0;padding:0;} #content{position: relative;margin:0 auto;} .box{padding:10px;float: left;} .box img{width: 180px;height:auto;display: block;} </style> <script src="https://www.jb51.net/js/jquery-1.11.1.min.js"></script> <script> $(function(){ waterfall(); //改变窗口大小时,重新排列 $(window).resize(function(){ waterfall(); }) //如果数据不够,没出现滚动条,自动加载数据 var time=setInterval(function(){ if(checkscrollside()){ addDate();//插入数据 waterfall();//加载完数据从新排列 }else{ clearInterval(time); $(window).scroll(function(){ if(checkscrollside()){ addDate(); waterfall(); }; }) } },1000) }) // 数据插入 function addDate(){ var dataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模拟数据,也可以是对象 var oParent = $('#content'); for(var i=0;i<dataInt.length;i++){//循环插入数据 oParent.append('<div><img src="./img/'+dataInt[i]+'" alt=""></div>'); } } //主函数 function waterfall(){ var arrBox=$('#content').children('.box');// box对象 var iBoxW=arrBox.eq(0).innerWidth();// 获取瀑布流块的宽度,注意width(),跟innerWidth()的区别 var num=Math.floor($(window).width()/iBoxW);//计算窗口能容纳几列 $('#content').css('width',iBoxW*num);//设置父级宽度 var arrBoxH=[];//数组,用于存储每列中的所有块框相加的高度 for(var i=0;i<arrBox.length;i++){//遍历数组瀑布流 块 var boxH=arrBox.eq(i).innerHeight();//获取当前块的高度 if(i<num){ arrBox.eq(i).attr('style','');//防止用户改变窗口大小,到时样式出错 arrBoxH[i]=boxH; //第一行中的num个块box 先添加进数组arrBoxH }else{ var minH=Math.min.apply(null,arrBoxH);//获取数组arrBoxH中的最小值minH var minHIndex=$.inArray(minH,arrBoxH);//使用jquery提供的工具 arrBox.eq(i).css({'position':'absolute','top':minH,'left':minHIndex*iBoxW});//设置定位 arrBoxH[minHIndex]+=arrBox.eq(i).innerHeight();//添加后,更新最小列高 } } } // 判断滚动条是否到底部 function checkscrollside(){ var arrBox=$('#content').children('.box'); //获取最后一个瀑布流块的高度:距离网页顶部(实现未滚到底就开始加载) var lastBoxH=arrBox.eq(arrBox.length-1).offset().top; var scrollTop=$(window).scrollTop()//获取滚动条卷走的高度 var documentH=$(window).height();;//显示页面文档的高 return (lastBoxH<scrollTop+documentH)?true:false;//到达指定高度后 返回true,触发waterfall()函数 } </script> </head> <body> <div> <div><img src="https://www.jb51.net/img/0.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/1.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/2.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/3.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/4.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/5.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/6.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/7.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/8.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/9.jpg" alt=""></div> <div><img src="https://www.jb51.net/img/10.jpg" alt=""></div> </div> </body> </html>
大致思路
1.先让第一行的浮动
2.计算第一行的每个块的高度
3.遍历第一行之后的每一个块,逐个放在最小高度的下面
4.加载数据插入最后,再重新计算
注意点
a.原生js
1.定义了getClassObj()函数用于获取class类的对象,方便调用。考虑了兼容性 getElementsByClassName
2.定义了getminHIndex()函数用户获取最小值的索引
3.设置块与块之间的距离最好用padding,这样的话offsetHeight可以直接获取得到高度。如果设置margin则得多加个外边距的距离
4.代码中设置了定时器加载数据,其实可以省略,只要保证第一次加载的数据能满屏就可以。如果没出现滚动条的话onscroll事件是不会执行到的。也就没办法加载数据了
5.代码中的计算宽度也可以修改,设计的页面是定宽的瀑布流的话。这里主要是做了响应式的处理