我使用以下代码预加载相册图片并显示加载栏。
var album1 = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg'];
var album2 = ['01.jpg', '02.jpg', '03.jpg', '04.jpg', '05.jpg'];
var total_images = album1.length + album2.length;
var load_count = 0;
$(document).ready(function() {
function preloadImages(list, path) {
var img;
if (!preloadImages.cache) {
preloadImages.cache = [];
}
for (var i = 0; i < list.length; i++) {
img = new Image();
$(img).bind('load', function() {
load_count++;
$('#loading_bar #progress').css('width', Math.round(load_count * 100 / total_images) + '%');
if(load_count >= total_images) {
init_sequence();
}
});
img.src = path + list[i];
preloadImages.cache.push(img);
}
}
preloadImages(album1, 'http://www.example.com/images/path1/');
preloadImages(album2, 'http://www.example.com/images/path2/');
}
上述预加载代码在正常网络条件下工作正常。但是,当网络不稳定时,无法加载其中一个图像时,无法触发函数init_sequence()
。
我的问题是,如何在预加载图像时设置超时(可能在上面的函数上使用setTimeout()
)(例如,如果预加载无法在30秒内完成,反正加载init_sequence()
)?< / p>
其他信息:
如果有人需要知道HTML结构,这里是(允许我只显示<body>
部分;我肯定包含了jQuery):
<body>
<div id="loading_bar">
<div id="progress"></div>
</div>
</body>
和CSS:
#loading_bar {
position: fixed;
left: 0;
bottom: 0;
height: 5px;
width: 100%;
background-color: #EEE;
}
#loading_bar #progress {
position: relative;
left: 0;
height: 5px;
width: 0;
background-color: #A68029;
}
答案 0 :(得分:2)
只需使用如下的超时变量。
var album1 = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg'];
var album2 = ['01.jpg', '02.jpg', '03.jpg', '04.jpg', '05.jpg'];
var total_images = album1.length + album2.length;
var load_count = 0;
$(document).ready(function() {
// A flag to check if loading timeout had been reached
var loadTimeout = false;
function preloadImages(list, path) {
var img;
if (!preloadImages.cache) {
preloadImages.cache = [];
}
for (var i = 0; i < list.length; i++) {
img = new Image();
$(img).bind('load', function() {
load_count++;
$('#loading_bar #progress').css('width', Math.round(load_count * 100 / total_images) + '%');
if(load_count >= total_images) {
// If we get this far, then clear the timeout variable
clearTimeout(timeout);
// If the image is loaded after timeout, then do nothing because init_sequence have been called.
if (loadTimeout == false) {
init_sequence();
}
}
});
img.src = path + list[i];
preloadImages.cache.push(img);
}
}
// Set timeout for 30 seconds
var timeout = setTimeout(function() {
loadTimeout = true;
init_sequence();
}, 30000);
preloadImages(album1, 'http://www.example.com/images/path1/');
preloadImages(album2, 'http://www.example.com/images/path2/');
}
答案 1 :(得分:0)
var initialized = false;
function init_sequence(){
if (initialized)
return;
initialized = true;
//...
}
setTimeout(init_sequence, 30000);
在我的情况下,它会是这样的(或者我使用承诺而不是观察者),我喜欢这样......但我不认为这对你来说是可以接受的; - )
var Observer = function (){
this.listeners = {};
};
Observer.prototype = {
constructor: Observer,
register: function (type){
this.listeners[type] = [];
},
on: function (type, callback){
this.listeners[type].push(callback);
},
off: function (type){
this.listeners[type].length = 0;
},
trigger: function (type){
var args = Array.prototype.slice.call(arguments, 1);
var listeners = this.listeners[type];
for (var i=0, l=listeners.length; i<l; ++i){
var listener = listeners[i];
}
}
};
var Map = function (){
this.data = {};
};
Map.prototype = {
constructor: Map,
length: 0,
set: function (key, value){
if (!this.has(key))
++this.length;
this.data[key] = value;
},
has: function (key){
return this.data.hasOwnProperty(key);
},
get: function (key){
if (this.has(key))
return this.data[key];
},
remove: function (key){
if (this.has(key))
--this.length;
delete(this.data[key]);
},
each: function (callback){
for (var key in this.data)
if (this.has(key))
callback(this.get(key), key);
}
};
var ImagePreloader = function (){
this.loaded = new Map();
this.loading = new Map();
this.observer = new Observer();
this.observer.register("progress");
this.observer.register("complete");
};
ImagePreloader.prototype = {
constructor: ImagePreloader,
on: function (type, callback){
this.observer.on(type, callback);
},
off: function (type){
this.observer.off(type);
},
trigger: function (type){
this.observer.trigger.apply(this.observer, arguments);
},
percent: function (){
var totalCount = this.loading.length + this.loaded.length;
if (!totalCount)
return 0;
return Math.round(100 * this.loading.length / totalCount);
},
load: function (url){
if (this.loading.has(url) || this.loaded.has(url))
return;
var image = new Image();
this.loading.set(url, image);
$(image).bind("load", function() {
this.success(url);
}.bind(this));
image.src = url;
this.progress();
},
success: function (url){
var image = this.loading.get(url);
this.loading.remove(url);
this.loaded.set(url, image);
this.progress();
},
progress: function (){
var percent = this.percent();
this.observer.trigger("progress", percent);
if (percent == 100)
this.observer.trigger("complete");
}
}
var ProgressBar = function (){
};
ProgressBar.prototype = {
constructor: ProgressBar,
$el: null,
percent: 0,
setElement: function (el){
this.$el = $(el);
},
setProgress: function (percent){
this.percent = percent;
},
render: function (){
if (!this.$el)
return;
this.$el.css("width", this.percent + "%");
}
};
var Album = function (baseUrl, pathes){
this.baseUrl = baseUrl || "/";
this.images = new Map();
if (pathes)
this.pushAll(pathes);
};
Album.prototype = {
constructor: Album,
length: 0,
pushAll: function (pathes){
for (var i=0, l=pathes.length; i<l; ++i)
this.push(images[i]);
},
push: function (path){
var url = baseUrl + path;
this.images.set(path, url);
this.length = this.images.length;
},
each: function (callback){
this.images.each(callback);
}
};
var Main = {
run: function (){
var albums = this.createAlbums();
this.preloadAlbums(albums, this.renderAlbums.bind(this));
},
createAlbums: function (){
var albums = new Map();
albums.set("album1", new Album(
'http://www.example.com/images/path1/',
['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg']
));
albums.set("album2", new Album(
'http://www.example.com/images/path2/',
['01.jpg', '02.jpg', '03.jpg', '04.jpg', '05.jpg']
));
return albums;
},
preloadAlbums: function (albums, complete){
var timeoutSeconds = 30;
var progressBar = new ProgressBar();
$(document).ready(function() {
progressBar.setElement('#loading_bar #progress');
});
var preloader = new ImagePreloader();
preloader.on("progress", function (percent){
progressBar.setProgress(percent);
progressBar.render();
});
preloader.on("complete", function (){
preloader.off("complete");
complete(albums);
});
albums.each(function (album){
album.each(function (url){
preloader.load(url);
});
});
setTimeout(function (){
preloader.trigger("complete");
}, timeoutSeconds * 1000);
},
renderAlbums: function (albums){
init_sequence();
}
};
Main.run();
顺便说一下。我不认为你必须等到ready
开始预装图片......