手机端懒加载之没有图片高宽的瀑布流实现

发表于 2016-12-19 11:35:46   |   下载附件   |   字体:
瀑布流懒加载预加载图片得到高宽滚动加载更多

今天项目中用到了瀑布流效果,所有效果由前端渲染,得到一个图片地址,没有图片高宽,也不知道图片能不能加载成功,为此,必须先预加载图片,得到图片的真实高宽再计算显示高宽和它所处的位置信息,才能实现瀑布流效果,直接贴代码:


// 瀑布流函数
var waterfall = {
	// 初始变量
	w:0,
	c1:0,
	c2:0,
	min:0,
	max:0,
	h:0, 
	loads:0,
	itemPrevID:null,
	itemWrap:null,
	complete:null,
	// 重置初始化数据
	reset:function(){
		this.w = 0;
		this.c1 = 0;
		this.c2 = 0;
		this.min = 0;
		this.max = 0;
		this.h = 0; 
		this.loads = 0;
		this.complete = null;
	},
	// 懒加载并计算图片的高宽
	getImgSize:function(imgNode,callback) {
		// 版本检测
		var testIE = function(){
			var t , vesion,
				ua = navigator.userAgent.toLowerCase(),
				ie = /msie ([0-9])\.0/;
			if((t=ie.exec(ua))!=null){
				vesion = t[1];
			}
			return vesion;
		};
		var tempURL = imgNode.src;
		var sUrl = $(imgNode).data('src');
		// 加载图片
	    // var img = new Image();
	    imgNode.src = sUrl + '?t=' + Math.random();
	    if( testIE() <= 10 ){
			imgNode.onreadystatechange = function() {
		        if (this.readyState == "loaded" || this.readyState == "complete") {
		        	var imgHeight = imgNode.height * ( (waterfall.w - 20) / imgNode.width ) ;
		        	$(imgNode).css({width:waterfall.w-20,height:imgHeight});
		            callback({
		                width: imgNode.width,
		                height: imgNode.height,
		                sw: waterfall.w-20,
		                sh: imgHeight,
		                url: sUrl,
		                node:imgNode,
		                errorAlt:null,
	                	error:false
		            });
		        }
		    };
		    imgNode.onerror = function() {
				$(imgNode).css({width:waterfall.w-20,height:waterfall.w-20});
		        callback({
	                width: waterfall.w-20,
	                height: waterfall.w-20,
	                sw: waterfall.w-20,
	                sh: waterfall.w-20,
	                url: sUrl,
	                node:imgNode,
	                errorAlt:tempURL,
	                error:true
	            });
		    };
		}else{
			imgNode.onload = function() {
				var imgHeight = imgNode.height * ( (waterfall.w - 20) / imgNode.width ) ;
				$(imgNode).css({width:waterfall.w-20,height:imgHeight});
		        callback({
	                width: imgNode.width,
	                height: imgNode.height,
	                sw: waterfall.w-20,
	                sh: imgHeight,
	                url: sUrl,
	                node:imgNode,
	                errorAlt:null,
	                error:false
	            });
		    };
		    imgNode.onerror = function() {
				$(imgNode).css({width:waterfall.w-20,height:waterfall.w-20});
		        callback({
	                width: waterfall.w-20,
	                height: waterfall.w-20,
	                sw: waterfall.w-20,
	                sh: waterfall.w-20,
	                url: sUrl,
	                node:imgNode,
	                errorAlt:tempURL,
	                error:true
	            });
		    };
		}
	},
	// 加载瀑布流图片
	getImgList:function(startNum,entNum){
		for(var i = startNum; i < entNum; i++){
			var img =  $(this.itemPrevID+(i+1)).find('img').get(0);
			this.getImgSize(img,function(o){
				if(o.error){
					console.log(o.errorAlt);
				}
				waterfall.loads++;
				console.log(waterfall.loads);
			});
		}
	},
	// 加载完成显示瀑布流
	showList:function(startNum,entNum){
		for(var i = startNum; i < entNum; i++){
			var obj = $(waterfall.itemPrevID+(i+1));
			this.min = Math.min(this.c1, this.c2);
			obj.css({top:this.min + "px"});
			this.h = obj.height();
			if(this.c1 == this.min){
				obj.css({left:0});
				this.c1 += this.h + 10;
			}else if(this.c2 == this.min){
				obj.css({left:'50%'});
				this.c2 += this.h + 10;
			}
			obj.get(0).style.visibility = "visible";
		}
		this.max = Math.max(this.c1, this.c2);
		$(this.itemWrap).css({height:this.max + "px"});
		if(this.complete){
			this.complete();
		}
	},
	// 瀑布流
	setList:function(startNum,entNum,isLoad){
		// 是否加载了图片 不加载没有图片及容器高度
		if(isLoad){
			// 加载是否完成
			if( waterfall.loads < entNum ){
				// 等待加载完成后执行
				window.setTimeout(function(){
					waterfall.setList(startNum,entNum,1);
				},500);
			}else{
				// 这里加载完成了
				waterfall.showList(startNum,entNum);
			}
		}else{
			// 先加载图片
			waterfall.getImgList(startNum,entNum);
			// 等待加载完成后执行
			window.setTimeout(function(){
				waterfall.setList(startNum,entNum,1);
			},200);
		}
	},
	// 默认初始化
	init:function(opts){
		// 设置图片宽度
		this.itemPrevID = opts.itemPrevID;
		this.itemWrap = opts.itemWrap;
		this.w = opts.width;
		if(opts.complete){
			this.complete = opts.complete;
		}
		this.setList(opts.start,opts.ent);
	}
}