瀑布流 + 无限加载效果
缺点:影响性能
主要实现步骤:
1.区分第一行和后面的行
2.第一行浮动
3.获取第一行所有的高度
4.找到最小高度的图片
5.后面进行定位
6.定位到上一行最矮图片的位置下
7.修改当前最小值(后面的图片一次加上最矮图片的高度)
8.从步骤4开始循环
//css
.cont{margin:0 auto;position: relative;}
/* 这里不用margin是因为offset识别不了margin,只能识别到padding */
.box{padding: 6px;float: left;}
.boxImg{padding: 6px;border: 1px solid #000;width:236px;border-radius: 6px;}
.boxImg img{width:236px;display:block;}
//body---这里的图片都是宽度固定的,高度不同的图片
<div class="cont">
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/331509d2fb8535afd56065fbabd3171ab55f609c11548-MUs1kW_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/e2cfbe4f99b305ed11a8330f6d35f72ce93447a714e4e-xfnq0D_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/d36242a162b58ea0df2a392d4602ab3e0bc5aa136be3a0-l2vPT8_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/2fc61915044eeefbdc7b45fd0dbf2b4b7cbf9f5977c26-hG0qEI_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/db4ea2c49cb840cd3439d6d25649ae06782fcee04d239-Ld3QA3_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/7ef96c19b6c2803c337498d0a0010ebc7c0f79916d887-ZVPibd_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/4e6a2caefc3010c91d971efe97b66df699fba8d961fae-t0Nd69_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/572afd078804a86d288b36aad96d9b1f648660c632a4f-7UeOUl_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/384a943e6e04b0a41faec5c54d842688049292d84db17-lX7qBE_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/2a4bbf27dee14c5d76bc0df3e7ad2b28eaa8b0811c4f6-fmuWgw_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/8fefd3c9e1cc23dabd3460d0b13fce9c5344f172bb26-x5gEPW_fw236" />
</div>
</div>
<div class="box">
<div class="boxImg">
<img src="http://hbimg.huabanimg.com/702793bf9304c7dd7e391d04923096a82a26ba848760e-JZd8ix_fw236" />
</div>
</div>
</div>
//js
function WaterFlow(){
this.cont = document.getElementsByClassName("cont")[0];
this.box = document.querySelectorAll(".box");
//获取可视区的宽度
this.clientW = document.documentElement.clientWidth;
this.data = [{
src:"http://hbimg.huabanimg.com/331509d2fb8535afd56065fbabd3171ab55f609c11548-MUs1kW_fw236"
},{
src:"http://hbimg.huabanimg.com/e2cfbe4f99b305ed11a8330f6d35f72ce93447a714e4e-xfnq0D_fw236"
},{
src:"http://hbimg.huabanimg.com/d36242a162b58ea0df2a392d4602ab3e0bc5aa136be3a0-l2vPT8_fw236"
},{
src:"http://hbimg.huabanimg.com/2fc61915044eeefbdc7b45fd0dbf2b4b7cbf9f5977c26-hG0qEI_fw236"
},{
src:"http://hbimg.huabanimg.com/db4ea2c49cb840cd3439d6d25649ae06782fcee04d239-Ld3QA3_fw236"
},{
src:"http://hbimg.huabanimg.com/7ef96c19b6c2803c337498d0a0010ebc7c0f79916d887-ZVPibd_fw236"
},{
src:"http://hbimg.huabanimg.com/4e6a2caefc3010c91d971efe97b66df699fba8d961fae-t0Nd69_fw236"
},{
src:"http://hbimg.huabanimg.com/572afd078804a86d288b36aad96d9b1f648660c632a4f-7UeOUl_fw236"
},{
src:"http://hbimg.huabanimg.com/384a943e6e04b0a41faec5c54d842688049292d84db17-lX7qBE_fw236"
},{
src:"http://hbimg.huabanimg.com/2a4bbf27dee14c5d76bc0df3e7ad2b28eaa8b0811c4f6-fmuWgw_fw236"
},{
src:"http://hbimg.huabanimg.com/8fefd3c9e1cc23dabd3460d0b13fce9c5344f172bb26-x5gEPW_fw236"
},{
src:"http://hbimg.huabanimg.com/702793bf9304c7dd7e391d04923096a82a26ba848760e-JZd8ix_fw236"
}]
//定义一个数组用来存放图片的高度
this.heightArr = [];
this.init();
this.addEvent();
}
WaterFlow.prototype.init = function(){
//通过可视区的宽度,得到一行最多能放几张图
this.maxNum = parseInt(this.clientW / this.box[0].offsetWidth);
//由图片的张数得到最外边容器的宽度
this.cont.style.width = this.maxNum * this.box[0].offsetWidth + "px"
this.firstLine();
this.followLine();
}
WaterFlow.prototype.firstLine = function(){
for(var i = 0;i < this.maxNum;i++){
//将第一行图片的高度存到数组中
this.heightArr.push(this.box[i].offsetHeight)
//console.log(this.heightArr)
}
}
WaterFlow.prototype.followLine = function(){
for(var i = this.maxNum;i < this.box.length;i++){
//获取一行最矮图片的高度
var min = getMin(this.heightArr);
//获取最矮图片高度的索引
var minIndex = this.heightArr.indexOf(min);
//给后面的图片定位
this.box[i].style.position = "absolute";
this.box[i].style.top = min + "px";
this.box[i].style.left = minIndex * this.box[0].offsetWidth + "px";
//后面的图片依次加上最矮图片的高度(注:当最矮的图片高度改变时它就不是最矮的,最矮的应该是原来的倒数第二个)
this.heightArr[minIndex] += this.box[i].offsetHeight;
}
}
WaterFlow.prototype.addEvent = function(){
var that = this;
var clientH = document.documentElement.clientHeight;
onscroll = function(){
var lastTop = that.box[that.box.length - 1].offsetTop;
var scrollT = document.documentElement.scrollTop;
//console.log(clientH,lastTop,scrollT)
if(lastTop <= scrollT + clientH){
that.display();
}
}
}
WaterFlow.prototype.display = function(){
var str = "";
for(var i = 0;i < this.data.length;i++){
str += `<div class="box">
<div class="boxImg">
<img src="${this.data[i].src}" />
</div>
</div>`
}
this.cont.innerHTML += str;
//重新获取所有的box
this.box = document.querySelectorAll(".box");
//初始化高度,因为马上要重新渲染整个页面了
this.heightArr = [];
this.init();
}
function getMin(arr){
//浅拷贝,会影响值,所以通过json改成深拷贝
var myarr = JSON.parse(JSON.stringify(arr))
return myarr.sort((a,b)=>a-b)[0];
}
window.onload = function(){
new WaterFlow()
}