问答详情
源自:2-4 将无序预加载写成jQuery插件

卡在0%,对了好几遍找不到原因

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
html,body{
height: 100%;
}
a{
text-decoration: none;
}
.box{
text-align: center;
}
.btn{
display: inline-block;
height: 30px;
line-height: 30px;
border: 1px solid #ccc;
background-color: #fff;
padding: 0 10px;
margin-right: 50px;
color: #333;
}
.btn:hover{
background-color: #eee;
}
.loading{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #eee;
text-align: center;
font-size: 30px;
}
.progress{
margin-top: 300px;
}

</style>
</head>
<body>
<div>
<img src="http://i2.hoopchina.com.cn/user/308/15960308/13383588090.jpg" alt="pic" id="img" width="1200" />
<p>
<a href="javascript:;" data-control="precv">上一页</a>
<a href="javascript:;" data-control="next">下一页</a>
</p>
</div>

<div>
<p>0%</p>
</div>

<script type="text/javascript" src="js/jquery-3.2.0.min.js"></script>
<script type="text/javascript" src="js/preload.js"></script>
<script type="text/javascript">
var imgs=[

'http://i2.hoopchina.com.cn/user/308/15960308/13383588090.jpg',

'http://img.article.pchome.net/00/44/23/20/pic_lib/wm/2.jpg ',

'http://lcd.yesky.com/imagelist/2009/044/404q4y8g4m0p.jpg ',

'http://lcd.yesky.com/imagelist/2009/044/cgro54wt2t2x.jpg '

];

// index表示当前是第几张图片
var index=0,
// count表示加载了几张图片
$progress=$(".progress"),
len=imgs.length;


$.preload(imgs,{
each:function(count){
$progress.html(Math.round((count+1)/len*100)+"%");
},
all:function(){
$(".loading").hide();
document.title="1/"+len;
}
});


$(".btn").on("click",function(){
if("prev"===$(this).data("control")){    //上一张

index=Math.max(0,--index);
}else{          //下一张
index=Math.min(len-1,++index);
}
document.title=(index+1)+"/"+len;

$("#img").attr("src",imgs[index]);
})
</script>
</body>
</html>

preload.js

// 图片预加载
// 使用闭包模拟局部作用域 使得内部的变量不会与外部产生冲突
// 将jQuery传入匿名函数中 并用$接收  在闭包函数内可以使用jQuery
(function($){
	function Preload(imgs,options){
		// 传递进来的参数是数组还是字符串
		this.imgs=(typeof imgs==="string")?[imgs]:imgs;
		this.opts=$.extend({},Preload.DEFAULTS,options);
		this._unoredered();
	}
	Preload.DEFAULTS={
		each:null,//每一张图片加载完毕后执行
		all:null  //所有图片加载完毕后执行
	}

	Preload.prototype._unoredered=function(){
		var imgs=this.imgs
			opts=this.opts,
			count=0,
			len=imgs.length;

		$.each(imgs,function(i,src){
			if(typeof src!="string")
				return;
			var imgObj=new Image();

			$(imgObj).on("load error",function(){
				$(imgObj).on("load error",function(){
					// 判断each是否存在
					opts.each && opts.each(count);

					if(count>=len-1){
						opts.all && opts.all();
					}
					count++;
				});

				imgObj.src=src;
			})
		})
	}

	$.extend({
		preload:function(imgs,opts){
			new Preload(imgs,opts);
		}
	});

})(jQuery);


提问者:weibo_happy的小小明_0 2017-06-09 19:07

个回答

  • _Rock
    2017-06-10 00:43:03
    已采纳

    细节问题:.html文件的 76行 p标签的类名和85行div的类名未加到对应的DOM结构. 当然这并不是导致无法加载图片的原因。

    一直卡在加载页面的问题是在.js文件的27行到39行之间,on('load',function())等价于onload事件,onload事件是在加载完毕才触发的事件,而在38行你将img的sec属性赋值放在了onload事件触发函数内,这就意味着在触发onload事件之前img元素没有初始化src属性,即不会去加载,也就不存在加载完毕。将imgObj.src=src;移到onload函数外部即可。注:不要尝试在onload触发函数修改img(加载控件)的src(资源地址),否则会进入死循环.另外27与28行两个onload绑定事件嵌套则完全没必要,

    附上js文件each遍历函数修改部分:

    $.each(imgs, function (i, src) {
        if (typeof src != "string")
            return;
        var imgObj = new Image();
        $(imgObj).on('load error', function () {
            // 判断each是否存在
            opts.each && opts.each(count);
            if (count >= len - 1) {
                opts.all && opts.all();
            }
            console.log(count);
            count++;
        });
        imgObj.src = src;
    });

    还有问题请回复,求采纳!