瀑布流在最短列添加图片失效
用ajax实现瀑布流,设置了在最短列添加图片,但是有时刷新,图片却一溜烟加在某列上
部分代码如下:
给每个img包裹一层div,判断最短列后,将div插入到该列下
原因:图片加载太慢
添加下一张图片,需要计算当前每个li高度,这时前面添加的图片还未完全获取到,导致高度的计算失效,如果没有padding,相当于每次加载图片,高度仅加0,新加载的图片一直加在某一列上,直至某张图片加载完成,才可能改变局势
就像这样:后面红色的框代表没有加载完成的图片,仅靠padding撑起高度,前面的红色框框里的img没有加载出来,第2列刚好本就短,所以堆积了第5、6、7张在第2列上,当这些padding累加起来,终于高度大于第4列了,才开始加在第4列上
实际上,我们计算offsetHeight时,应该计算前面添加的图片的实际高度,所以,在获取的图片信息中加上图片的实际宽高
所以,我们在加载图片数据时,要把图片的高度固定住,这样就能解决只有padding的问题了
在给img添加src时,也添加上img的高度:
多次重复请求数据
做新加载判断时,监听滚轮高度,设置了当窗口高度+滚动条高度 > 最短列高度时,就触发加载新的图片,但是,加载和插入需要时间,在这个时间内,我有滚动了滚轮,再一次触发滚轮滚动事件,此时还未完成新图片的加载,判断条件依然成立,就再一次触发请求
解决办法:设置锁,当前不在请求数据,才能请求数据
完整代码:
//分页
var num = 1;
//设置请求数据的锁
var flag = false; //false代表当前不在请求数据中
//调用ajax
function send(){
//当前不在请求数据中,才能触发请求
if (!flag){
myajax('GET', './getData.php', cbs, 'cpages='+num, true);
flag = true;
num++;
}
}
send();
//Ajax获取数据后执行该回调函数
var oLi = document.getElementsByTagName('li');
function cbs(data){
var data = JSON.parse(data);
if (data.length > 0){
data.forEach(function(ele, index){
var oItem = document.createElement('div');
oItem.className = 'item';
var oImg = document.createElement('img');
oImg.src = ele.imgSrc;
//图片等宽230px,对图片做了缩放,计算缩放后的高度
oImg.height = ele.height * 230 / ele.width;
oItem.appendChild(oImg);
//在最短列添加新加载的图片
oLi[findShortest(oLi)].appendChild(oItem);
})
// 数据加载完成并插入后,才开放请求数据的权限
flag = false;
}else {
alert('已无数据')
}
}
/*
* 判断高度最短的列,返回列索引
* lis:所有li
* index:最短li的索引
*/
function findShortest(lis){
var len = lis.length,
min = lis[0].offsetHeight,
index = 0;
for (var i = 0; i < len; i++){
var h = lis[i].offsetHeight;
if (h < min){
min = h;
index = i
}
}
return index;
}
//解决多次重复发送请求
window.onscroll = function(){
var index = findShortest(oLi);
var h = oLi[index].offsetHeight;
var clientHeight = document.documentElement.clientHeight || document.body.clientHeight,
scrollHeight = document.documentElement.scrollTop || document.body.scrollTop;
console.log(clientHeight,scrollHeight,h);
if (clientHeight + scrollHeight > h){
send();
}
}