我很难在一个方面调整jQuery图像预加载脚本:我无法弄清楚如何确保我的图像按照图像阵列的顺序加载/显示。
每次重新加载页面时,图像都会以不同的顺序显示。 (除了图像顺序之外的所有内容都可以正常工作。)
任何人都可以帮我解决这个问题吗?
相关代码:
(function($) {
var imgList = [];
$.extend({
preload: function(imgArr, option) {
var setting = $.extend({
init: function(loaded, total) {},
loaded: function(img, loaded, total, bild) {},
loaded_all: function(loaded, total) {}
}, option);
var total = imgArr.length;
var loaded = 0;
setting.init(0, total);
for (var i = 0; i < total; i++) {
imgList[i] = ($("<img />")
.attr("src", imgArr[i])
.load(function() {
loaded++;
setting.loaded(this, loaded, total, this.src);
if(loaded == total) {
setting.loaded_all(loaded, total);
}
})
);
}
}
});
})(jQuery);
$(document).ready(function() {
$(function() {
$.preload([
"image1.jpg",
"image2.jpg",
"image3.jpg"
], {
init: function(loaded, total) {
var z = 0;
while (z < total) {
z++;
$("section nav").append('<img id="e'+z+'" src="all/blank.png" alt=""/>');
}
},
loaded: function(img, loaded, total, bild) {
$("#e"+loaded).prop("src",bild);
},
loaded_all: function(loaded, total) {
//all done!
}
});
});
});
更新
最后,我用一个完全不同的,更短的脚本解决了它,我从头开始编写。它开始添加尽可能多(非常小)的虚拟图像作为占位符到我的图像容器,因为数组包含真实图像并仅在前一个图像完成后加载每个图像:
imgs = new Array("number1.png","number2.png","number3.png");
for (i=0; i<imgs.length; i++) {
$("section nav").append('<img id="e'+i+'" src="blank.png" alt=""/>');
}
fin(0);
function fin (n) {
$('#e'+n).attr('onload', 'fin('+n+')');
$("#e"+n).attr("src", imgs[n]).load( function() {
fin ((n+1));
});
}
答案 0 :(得分:1)
问题是您将加载的img附加到当前加载的图像数量的位置,即图像按照加载的顺序放置。
您实际上希望在var i
上订购它们:
for (var i = 0; i < total; i++) {
imgList[i] = ($("<img />")
.attr("src", imgArr[i])
.load(function() {
loaded++;
setting.loaded(this, i, total, this.src); // i instead of loaded
if(loaded == total) {
setting.loaded_all(loaded, total);
}
})
);
}
但这不起作用,因为i
在加载图片时与total
相同,因此所有图片都会转到total
位置。不是你想要的!
所以我们需要将它包装在一个自调用匿名函数中,以获取对正确的i
值的访问权限:
for (var i = 0; i < total; i++) {
// wrap in function to get access to the right i
(function(img) {
imgList[img] = ($("<img />")
.attr("src", imgArr[img])
.load(function() {
loaded++;
setting.loaded(this, img, total, this.src); // img instead of i
if(loaded == total) {
setting.loaded_all(loaded, total);
}
})
);
})(i);
}
用这个替换你的for循环,它应该可以工作。
答案 1 :(得分:0)
除非您延迟下载每个图像直到完成上一个(这不是一个坏主意),否则您无法保证它们将以何种顺序下载。
浏览器通常会并行下载多个图像,以优化吞吐量。将其与不可预测的下载速度和不同的文件大小相结合,文件将以几乎任何顺序完成。
如果是您想要的视觉效果,您必须单独解决。
答案 2 :(得分:0)
由于图像异步加载,因此永远不会按顺序调用loaded
回调。但是,您应该更改loaded_all
以传递原始数组。这样你的处理程序就可以按顺序处理图像。
if(loaded == total) {
setting.loaded_all(imgArray);
}