瀑布流的实现方式(原生js+jquery+css3)
前言
项目需求要弄个瀑布流的页面,用的是waterfall这个插件,感觉还是可以的,项目赶就没自己的动手写。最近闲来没事,就自己写个。大致思路理清楚,还是挺好实现的...
原生javascript版
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<title>瀑布流-javascript</title>
<style>
*{margin:0;padding:0;}
#content{position:relative;margin:0auto;}
.box{padding:10px;float:left;}/*首行浮动,第二行开始绝对定位*/
.boximg{width:180px;height:auto;display:block;}
</style>
<script>
window.onload=function(){
waterfall('content','box');
//改变窗口大小时,重新排列
window.onresize=function(){
waterfall('content','box');
}
//如果数据不够,没出现滚动条,自动加载数据
vartime=setInterval(function(){
if(checkscrollside()){
addDate();//插入数据
waterfall('content','box');//加载完数据从新排列
}else{
clearInterval(time);
window.onscroll=function(){
if(checkscrollside()){
addDate();
waterfall('content','box');
};
}
}
},1000)
}
//数据插入
functionaddDate(){
vardataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模拟数据,也可以是对象
varoParent=document.getElementById('content');
for(vari=0;i<dataInt.length;i++){//循环插入数据
varoBox=document.createElement('div');
oBox.className='box';
oParent.appendChild(oBox);
varoImg=document.createElement('img');
oImg.src='./img/'+dataInt[i];
oBox.appendChild(oImg);
}
}
//主函数
functionwaterfall(parentID,childClass){
varoParent=document.getElementById(parentID);
vararrBox=getClassObj(parentID,childClass);//getClassObj()获取子class的数组
variBoxW=arrBox[0].offsetWidth;//获取瀑布流块的宽度
varnum=Math.floor(document.documentElement.clientWidth/iBoxW);//计算窗口能容纳几列
oParent.style.width=iBoxW*num+'px';//设置父级宽度
vararrBoxH=[];//数组,用于存储每列中的所有块框相加的高度
for(vari=0;i<arrBox.length;i++){//遍历数组瀑布流块
varboxH=arrBox[i].offsetHeight;//获取当前块的高度
if(i<num){
arrBox[i].style.cssText="";//防止用户改变窗口大小,到时样式出错
arrBoxH[i]=boxH;//第一行中的num个块box先添加进数组arrBoxH
}else{
varminH=Math.min.apply(null,arrBoxH);//获取数组arrBoxH中的最小值minH
varminHIndex=getminHIndex(arrBoxH,minH);//遍历数组获取最小值minH的索引
arrBox[i].style.position='absolute';//设置绝对位移
arrBox[i].style.top=minH+'px';
arrBox[i].style.left=minHIndex*iBoxW+'px';//也可以直接获取arrBox[minHIndex].offsetLeft
arrBoxH[minHIndex]+=arrBox[i].offsetHeight;//添加后,更新最小列高
}
}
}
//获取子class的数组
functiongetClassObj(parentID,childClass){
varoParent=document.getElementById(parentID);
varallChildObj=oParent.getElementsByTagName('*');//获取父级下的所有子集
varchildObj=[];//创建一个数组用于收集子元素
for(vari=0;i<allChildObj.length;i++){//遍历子元素、判断类别、压入数组
if(allChildObj[i].className==childClass){
childObj.push(allChildObj[i]);
}
};
returnchildObj;
}
//获取数组最小值的索引
functiongetminHIndex(arr,minH){
for(variinarr){
if(arr[i]==minH){
returni;
}
}
}
//判断滚动条是否到底部
functioncheckscrollside(){
vararrBox=getClassObj("content",'box');
//获取最后一个瀑布流块的高度:距离网页顶部(实现未滚到底就开始加载)
varlastBoxH=arrBox[arrBox.length-1].offsetTop;
varscrollTop=document.documentElement.scrollTop||document.body.scrollTop;//获取滚动条卷走的高度
vardocumentH=document.documentElement.clientHeight;//显示页面文档的高
return(lastBoxH<scrollTop+documentH)?true:false;//到达指定高度后返回true,触发waterfall()函数
}
</script>
</head>
<body>
<divid="content">
<divclass="box"><imgsrc="img/0.jpg"alt=""></div>
<divclass="box"><imgsrc="img/1.jpg"alt=""></div>
<divclass="box"><imgsrc="img/2.jpg"alt=""></div>
<divclass="box"><imgsrc="img/3.jpg"alt=""></div>
<divclass="box"><imgsrc="img/4.jpg"alt=""></div>
<divclass="box"><imgsrc="img/5.jpg"alt=""></div>
<divclass="box"><imgsrc="img/6.jpg"alt=""></div>
<divclass="box"><imgsrc="img/7.jpg"alt=""></div>
<divclass="box"><imgsrc="img/8.jpg"alt=""></div>
<divclass="box"><imgsrc="img/9.jpg"alt=""></div>
<divclass="box"><imgsrc="img/10.jpg"alt=""></div>
</div>
</body>
</html>
jquery版本
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<title>瀑布流-jquery</title>
<style>
*{margin:0;padding:0;}
#content{position:relative;margin:0auto;}
.box{padding:10px;float:left;}
.boximg{width:180px;height:auto;display:block;}
</style>
<scriptsrc="js/jquery-1.11.1.min.js"></script>
<script>
$(function(){
waterfall();
//改变窗口大小时,重新排列
$(window).resize(function(){
waterfall();
})
//如果数据不够,没出现滚动条,自动加载数据
vartime=setInterval(function(){
if(checkscrollside()){
addDate();//插入数据
waterfall();//加载完数据从新排列
}else{
clearInterval(time);
$(window).scroll(function(){
if(checkscrollside()){
addDate();
waterfall();
};
})
}
},1000)
})
//数据插入
functionaddDate(){
vardataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模拟数据,也可以是对象
varoParent=$('#content');
for(vari=0;i<dataInt.length;i++){//循环插入数据
oParent.append('<divclass="box"><imgsrc="./img/'+dataInt[i]+'"alt=""></div>');
}
}
//主函数
functionwaterfall(){
vararrBox=$('#content').children('.box');//box对象
variBoxW=arrBox.eq(0).innerWidth();//获取瀑布流块的宽度,注意width(),跟innerWidth()的区别
varnum=Math.floor($(window).width()/iBoxW);//计算窗口能容纳几列
$('#content').css('width',iBoxW*num);//设置父级宽度
vararrBoxH=[];//数组,用于存储每列中的所有块框相加的高度
for(vari=0;i<arrBox.length;i++){//遍历数组瀑布流块
varboxH=arrBox.eq(i).innerHeight();//获取当前块的高度
if(i<num){
arrBox.eq(i).attr('style','');//防止用户改变窗口大小,到时样式出错
arrBoxH[i]=boxH;//第一行中的num个块box先添加进数组arrBoxH
}else{
varminH=Math.min.apply(null,arrBoxH);//获取数组arrBoxH中的最小值minH
varminHIndex=$.inArray(minH,arrBoxH);//使用jquery提供的工具
arrBox.eq(i).css({'position':'absolute','top':minH,'left':minHIndex*iBoxW});//设置定位
arrBoxH[minHIndex]+=arrBox.eq(i).innerHeight();//添加后,更新最小列高
}
}
}
//判断滚动条是否到底部
functioncheckscrollside(){
vararrBox=$('#content').children('.box');
//获取最后一个瀑布流块的高度:距离网页顶部(实现未滚到底就开始加载)
varlastBoxH=arrBox.eq(arrBox.length-1).offset().top;
varscrollTop=$(window).scrollTop()//获取滚动条卷走的高度
vardocumentH=$(window).height();;//显示页面文档的高
return(lastBoxH<scrollTop+documentH)?true:false;//到达指定高度后返回true,触发waterfall()函数
}
</script>
</head>
<body>
<divid="content">
<divclass="box"><imgsrc="img/0.jpg"alt=""></div>
<divclass="box"><imgsrc="img/1.jpg"alt=""></div>
<divclass="box"><imgsrc="img/2.jpg"alt=""></div>
<divclass="box"><imgsrc="img/3.jpg"alt=""></div>
<divclass="box"><imgsrc="img/4.jpg"alt=""></div>
<divclass="box"><imgsrc="img/5.jpg"alt=""></div>
<divclass="box"><imgsrc="img/6.jpg"alt=""></div>
<divclass="box"><imgsrc="img/7.jpg"alt=""></div>
<divclass="box"><imgsrc="img/8.jpg"alt=""></div>
<divclass="box"><imgsrc="img/9.jpg"alt=""></div>
<divclass="box"><imgsrc="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.代码中的计算宽度也可以修改,设计的页面是定宽的瀑布流的话。这里主要是做了响应式的处理
vararrBox=getClassObj(parentID,childClass);//getClassObj()获取子class的数组 variBoxW=arrBox[0].offsetWidth;//获取瀑布流块的宽度 varnum=Math.floor(document.documentElement.clientWidth/iBoxW);//计算窗口能容纳几列 oParent.style.width=iBoxW*num+'px';//设置父级宽度
6.每设置一块位移,都要在列高的数组上增加数值,防止块重叠
arrBox[i].style.position='absolute';//设置绝对位移 arrBox[i].style.top=minH+'px'; arrBox[i].style.left=minHIndex*iBoxW+'px';//也可以直接获取arrBox[minHIndex].offsetLeft arrBoxH[minHIndex]+=arrBox[i].offsetHeight;//添加后,更新最小列高
b.jquery
1.思路是跟js一样的,只是jquery封装了很多方法,让我们简便的就实现了
2.注意width(),跟innerWidth()的区别。前者只能获取宽度值(不包括补白padding)
css3版本
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<title>瀑布流-css3</title>
<style>
*{margin:0;padding:0;}
#content{margin:0auto;position:relative;width:1200px;column-count:6;-moz-column-count:6;-webkit-column-count:6;}
.box{padding:10px;width:180px;}
.boximg{width:180px;height:auto;display:block;}
</style>
<script>
window.onload=function(){
//如果数据不够,没出现滚动条,自动加载数据
vartime=setInterval(function(){
if(checkscrollside()){
addDate();//插入数据
}else{
clearInterval(time);
window.onscroll=function(){
if(checkscrollside()){
addDate();
};
}
}
},1000)
}
//数据插入
functionaddDate(){
vardataInt=['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg'];//模拟数据,也可以是对象
varoParent=document.getElementById('content');
for(vari=0;i<dataInt.length;i++){//循环插入数据
varoBox=document.createElement('div');
oBox.className='box';
oParent.appendChild(oBox);
varoImg=document.createElement('img');
oImg.src='./img/'+dataInt[i];
oBox.appendChild(oImg);
}
}
//获取子class的数组
functiongetClassObj(parentID,childClass){
varoParent=document.getElementById(parentID);
varallChildObj=oParent.getElementsByTagName('*');//获取父级下的所有子集
varchildObj=[];//创建一个数组用于收集子元素
for(vari=0;i<allChildObj.length;i++){//遍历子元素、判断类别、压入数组
if(allChildObj[i].className==childClass){
childObj.push(allChildObj[i]);
}
};
returnchildObj;
}
//判断滚动条是否到底部
functioncheckscrollside(){
vararrBox=getClassObj("content",'box');
//获取最后一个瀑布流块的高度:距离网页顶部(实现未滚到底就开始加载)
varlastBoxH=arrBox[arrBox.length-1].offsetTop;
varscrollTop=document.documentElement.scrollTop||document.body.scrollTop;//获取滚动条卷走的高度
vardocumentH=document.documentElement.clientHeight;//显示页面文档的高
return(lastBoxH<scrollTop+documentH)?true:false;//到达指定高度后返回true,触发waterfall()函数
}
</script>
</head>
<body>
<divid="content">
<divclass="box"><imgsrc="img/0.jpg"alt=""></div>
<divclass="box"><imgsrc="img/1.jpg"alt=""></div>
<divclass="box"><imgsrc="img/2.jpg"alt=""></div>
<divclass="box"><imgsrc="img/3.jpg"alt=""></div>
<divclass="box"><imgsrc="img/4.jpg"alt=""></div>
<divclass="box"><imgsrc="img/5.jpg"alt=""></div>
<divclass="box"><imgsrc="img/6.jpg"alt=""></div>
<divclass="box"><imgsrc="img/7.jpg"alt=""></div>
<divclass="box"><imgsrc="img/8.jpg"alt=""></div>
<divclass="box"><imgsrc="img/9.jpg"alt=""></div>
<divclass="box"><imgsrc="img/10.jpg"alt=""></div>
</div>
</body>
</html>
注意点
1.滚动加载还是得另外加js
2.加载的数据,是竖向排列的。体验不是很友好
3.有兼容性问题,InternetExplorer10+
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。