您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页JS原生瀑布流效果实现

JS原生瀑布流效果实现

来源:化拓教育网


我们已经取得了列数之后呢我们第一排的图片肯定是一排宽度相等,长度不一是吧,也就是说,我们第二排的图片需要接上第一排图片的后边,我们不能一排一排操作,但我们可以一个一个操作,怎么操作呢,我们可以取到第一排高度最小的将下一张图片,也就是如果第一排7个,那下一个就是第八个,把第八个图片放在最小高度的图片上,如何实现呢,我们先试想一下,我们首先需要求出第一排中最小,我们有一个Math.min求最小,但是呢我们这个函数无法传入用数组,只能是具体的数怎么半呢,apply来扩展作用域
用代码展示下

var hArr=[];//每一列高度的值
 for (var i = 0; i < oBoxs.length; i++) {
 if(i<clos){//先记录好第一排高度
 hArr.push(oBoxs[i].offsetHeight);//放进去
 }else{//如果到达第二排,就开始计算
 var minH=Math.min.apply(Math,hArr);最小值计算
 //为什么可以呢,本来不能传数组,我们通过apply绑定作用域在Math上,也就是说还是执行这个函数但是,apply第二个参数需要是数组,所以间接地把参数变成了数组传进去,也就是说我们还是用了Math函数但值变成了数组里的值。
 //console.log(minH)
 var index=getMinhIndex(hArr,minH)//获取索引
 oBoxs[i].style.position="absolute";我们就可以找到,传入数组和最小值
 oBoxs[i].style.top=minH+"px";那下一张图片的高度救球出来了
 oBoxs[i].style.left=oBoxW*index+"px";左边的距离就是索引乘以元素的宽
 hArr[index]+=oBoxs[i].offsetHeight;//我们添加了一个图片后需要刷新数组里的高度,再去寻找下一个最小的,再向他的下面添加图片,一次循环
 }
 };
function getMinhIndex (arr,val){
 for(var i in arr){//在其中找到最小值,返回索引
 if(arr[i]==val){
 return i;
 }
 }
}

以上就大体做出了一个瀑布流的样式,就差拖动滚动条加载了,这里面肯定需要后台的支持,在慕课上,老师做了一个伪处理,这里建议看慕课视频,有图解十分清楚,我用语言或图片不太好表达

var dataInt={"data":[{"src":'0.jpg'},{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'}]}//我们自己写一个json数据
 window.onscroll=function(){
 if(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 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;
 var height=document.body.clientHeight||document.documentElement.clientHeight;
 return(lastBoxH<scrollTop+height)?true:false;//如果页面距离顶部(包括滚轮)的距离比滚轮加页面距离小,那么就返回true
}

完整JS代码

window.onload=function(){
 waterfall('main','box');
 //json
 var dataInt={"data":[{"src":'0.jpg'},{"src":'1.jpg'},{"src":'2.jpg'},{"src":'3.jpg'}]}
 window.onscroll=function(){
 if(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(oBox.length)
 //计算整个页面的列数(页面宽/box宽)
 var oBoxW=oBoxs[0].offsetWidth;
 //console.log(oBoxW);
 var clos=Math.floor(document.documentElement.clientWidth/oBoxW)//求列数
 //console.log(clos)
 //设置main的宽
 oparent.style.cssText='width:'+oBoxW*clos+'px; margin :0 auto';
 var hArr=[];//每一列高度的值
 for (var i = 0; i < oBoxs.length; i++) {
 if(i<clos){
 hArr.push(oBoxs[i].offsetHeight);
 }else{
 var minH=Math.min.apply(Math,hArr);
 //console.log(minH)
 var index=getMinhIndex(hArr,minH)//索引
 oBoxs[i].style.position="absolute";
 oBoxs[i].style.top=minH+"px";
 oBoxs[i].style.left=oBoxW*index+"px";
 hArr[index]+=oBoxs[i].offsetHeight;//更改数组
 }
 };
 //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]);//取出传过来相等的className
 };
 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;
 var height=document.body.clientHeight||document.documentElement.clientHeight;
 return(lastBoxH<scrollTop+height)?true:false;
}

我的瀑布流图

以上所述是小编给大家介绍的JS原生瀑布流效果实现详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务