问答详情
源自:2-5 onscroll事件实现瀑布流布局的图片加载功能

发现BUG!窗口先缩小再放大后拖动滚动条图片列数没变,且最右列图片重叠!

window.onload=function(){
	waterfall('main','box');
	//假设后台需要加载的图片
	var dataInt={"data":[{'src':'16.jpg'},{'src':'17.jpg'},{'src':'18.jpg'},{'src':'19.jpg'},{'src':'20.jpg'},{'src':'21.jpg'},{'src':'22.jpg'},{'src':'23.jpg'},{'src':'24.jpg'},{'src':'25.jpg'},{'src':'26.jpg'},{'src':'27.jpg'},{'src':'28.jpg'},{'src':'29.jpg'},{'src':'30.jpg'},{'src':'31.jpg'},{'src':'32.jpg'},{'src':'33.jpg'},{'src':'34.jpg'},{'src':'35.jpg'},{'src':'36.jpg'},{'src':'37.jpg'},]}
	//滚动条滑动时间
	window.onscroll=function(){
		if(checkScrollSlide()){
			for(var i=0;i<dataInt.data.length;i++){
				var oParent=document.getElementById('main');
				var oDiv=document.createElement('div');
				oDiv.className='box';
				oParent.appendChild(oDiv);
				
				var oPic=document.createElement('div');
				oPic.className='pic';
				oDiv.appendChild(oPic);
				
				var oImg=document.createElement('img');
				oImg.src='img/water-fall/'+dataInt.data[i].src;
				oPic.appendChild(oImg);
				}
				waterfall('main','box');
			}
		}
	}
//将Main下的class='box'取出来	
function waterfall(parent,box){
	oParent=document.getElementById('main');
	oBox=getByClass(oParent,'box');
	//alert(oBox.length);//40
	
	//1、获取每列的宽
	oBoxW=oBox[0].offsetWidth;
	//2、获取列数
	cols=Math.floor(document.documentElement.clientWidth/oBoxW); 
	//3、列*宽=整个浏览器页面的宽度
	oParent.style.cssText="width:"+oBoxW*cols+"px;margin:0 auto;"
	//实现瀑布流布局
	var hArr=[];
	for(var i=0;i<oBox.length;i++){
		//获取第一行所有图片的高度
		if(i<cols){
			hArr.push(oBox[i].offsetHeight);
			}
		else{
			//获取第一行中高度最少的图片并在它之后开始排列
			var minH=Math.min.apply(null,hArr);
			//获取高度最少图片索引
			var index=getIndex(hArr,minH);
			//定位接下来的图片
			oBox[i].style.position='absolute';
			oBox[i].style.top=minH+'px';
			oBox[i].style.left=oBox[index].offsetLeft+'px';
			//***关键一步
			hArr[index]+=oBox[i].offsetHeight;
			}	
			
		}
	}	
function getByClass(obj,cls){	
	var element=obj.getElementsByTagName('*');
	var result=[];
	for(var i=0;i<element.length;i++){
		if(element[i].className==cls){
			result.push(element[i])
			}
		}
	return result;	//不能漏了这一步!!!	
}	

function getIndex(arr,val){
	for(i in arr){
		if (arr[i]==val){
			return i;
			}
		}
	}	
	
function checkScrollSlide(){
	var oParent=document.getElementById('main');
	var oBox=getByClass(oParent,'box');
	//当最后一张图片出现一半时距离他整个页面顶部距离
	var lastBoxH=oBox[oBox.length-1].offsetTop+Math.floor(oBox[oBox.length-1].offsetHeight/2);
	//滚动条移动距离和浏览器本身高度 *****图片解释在img文件夹里!!
	var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;
	var clientH=document.documentElement.clientHeight||document.body.clientHeight;
	return (lastBoxH<scrollTop+clientH)?true:false;
	}




	


提问者:little淇 2016-05-09 11:49

个回答

  • qq_D座小哥_0
    2016-11-19 01:44:44

    bug原因是第一行的元素未设置绝对定位,在缩小后第一行靠后的几列元素拥有了绝对定位,再放大后,列数变大,绝对定位没有取消,当再次加载后,多出来的几列的第一行元素执行的语句为:

    if (i<cols) {

        heiArr.push(aBox[i].offsetHeight);

    }

    因为有了绝对定位,但是没有给定top和left值,所以会出现重叠现象;

    解决办法一:

    开始判断前,先清除第一行元素的绝对定位:

    for (var i = 0; i < aBox.length; i++) {
        	for(var j = 0; j < cols ;j++){
               aBox[j].style.position="";
            }
        	if (i<cols) {
        		heiArr.push(aBox[i].offsetHeight);
        	}	

    解决办法二:

    循环开始后,给第一行的元素也加上绝对定位:

           if (i<cols) {
        		heiArr.push(aBox[i].offsetHeight);
        		aBox[i].style.position='absolute';
        		aBox[i].style.top=0;
        		aBox[i].style.left=i*oBoxW+"px";//oBoxW为元素宽度
        	}
            else{
        		var minH=Math.min.apply(null,heiArr);
        		var index=getMinhIndex(heiArr,minH);
        		aBox[i].style.position='absolute';
        		aBox[i].style.top=minH+"px";
        		aBox[i].style.left=aBox[index].offsetLeft+"px";
        		heiArr[index]+=aBox[i].offsetHeight;
        	}