原生JavaScript实现网页瀑布流布局
思路分析:
所谓瀑布流布局就是将宽度相同、高度不统一的图片,均匀地呈现在页面,同时下拉滚动条也具有无限加载图片的功能。
假设要求的页面图片有6列,按照要求第7张图片应该在第一行高度最低的图片之下,剩下的图片依次类推。由此可见,页面中的图片每一列的宽度固定,高度在时刻变化,所以只要知道每一排高度最低的图片的位置,就可以知道下一张图片的位置(top,left)。
下拉滚动条无限加载图片可以看作一个event,每当下拉滚动条达到一个条件就触发这个事件。我们假设当鼠标拉动滚动条到页面最后一张图片的一半位置时触发这个事件,显然触发条件就是:当滚动条滚动的距离加上页面高度大于页面高度加上图片高度的一半。
思路清晰后就是代码实现了。
html5、css3代码简述:
<div id="main"> 第一个id为main的大盒子作为父级元素相对定位,同时用来获取元素对象
<div class="box">第二个class为box的盒子用来设置各个图片之间的间隙让页面更美观
<div class="pic"><img src=""></div>第三个盒子用来放图片以及设置图片边框样式
</div>
</div>
Javascript代码:
window.onload=function(){
waterfall('main','box');
var dataInt={"data":[{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'},{"src":'4.jpg'}]};
window.onscroll=function(){
if(checkScrollSlide())
{ console.log(checkScrollSlide());
var oParent=document.getElementById('main');
//将数据快渲染到页面的尾部
for(var i=0;i<dataInt.data.length;i++)
{
var oBox=document.createElement('div');
oBox.className='box';
oParent.appendChild(oBox);
var oPic=document.createElement('div');
oPic.className='pic';
oBox.appendChild(oPic);
var oImg=document.createElement('img');
oImg.src="img/"+dataInt.data[i].src;
oPic.appendChild(oImg);
}
waterfall('main','box');
}
}
}
function waterfall(parent,box){
//将main下的所有class为box的元素取出来
var oParent=document.getElementById(parent);
var oBoxs=getByClass(oParent,box);
//console.log(oBoxs.length);
//计算整个页面显示的列数(页面宽/box的宽)
var oBoxW=oBoxs[0].offsetWidth;
//console.log(oBoxW);
var cols=Math.floor(document.documentElement.clientWidth/oBoxW);
//console.log(cols);
//设置main的宽
oParent.style.cssText='width:'+oBoxW*cols+'px;margin:0 auto';
var hArr=[];
for(var i=0;i<oBoxs.length;i++)
{
if(i<cols){
hArr.push(oBoxs[i].offsetHeight);
}
else
{
var minH=Math.min.apply(null,hArr);
//console.log(minH);
var index=getMinhIndex(hArr,minH);
//console.log(index);
oBoxs[i].style.position='absolute';
oBoxs[i].style.top=minH+'px';
//oBoxs[i].style.left=oBoxW*index+'px';
oBoxs[i].style.left=oBoxs[index].offsetLeft+'px';
hArr[index]+=oBoxs[i].offsetHeight;
//console.log(hArr[index]);
}
}
//console.log(hArr);
}
//根据class获取元素
function getByClass(parent,clsName){
var boxArr=new Array(), //用来存储获取到的所有class为box的元素
oElements=parent.getElementsByTagName('*');
for(var i=0;i<oElements.length;i++)
{
if(oElements[i].className==clsName)
{
boxArr.push(oElements[i]);
}
}
return boxArr;
}
function getMinhIndex(arr,val){
for(var i in arr){
if(arr[i]==val){
return i;
}
}
}
//检测是否具备了滚动加载数据库的条件
function checkScrollSlide(){
var oParent=document.getElementById('main');
var oBoxs=getByClass(oParent,'box');
var lastBoxH=oBoxs[oBoxs.length-1].offsetTop+Math.floor(oBoxs[oBoxs.length-1].offsetHeight/2);
var scrollTop=document.body.scrollTop ||document.documentElement.scrollTop;
//console.log(scrollTop);
var height= document.body.clientHeight ||document.documentElement.clientHeight;
//console.log(height);
return (lastBoxH<scrollTop+height)?true:false;
}
作为初学者,代码规范或许不入大家法眼,而且也没有使用太多dom对象的操作方法(都是通过视频教程以及参阅JS文档用函数完成),同时笔者也是第一次发博客,希望以此记录自己的学习经历, 错误之处以及不足之处请大家多多指正,在此不胜感激。