不幸的是,这取决于你的目的。如果你打算将图像用于样式目的,最好使用精灵图。 http://www.alistapart.com/articles/sprites2
但是如果你想在<img>标签中使用这些图像,那么你需要预加载它们。
function preload(sources)
{
var images = [];
for (i = 0, length = sources.length; i < length; ++i) {
images[i] = new Image();
images[i].src = sources[i];
}
}
以下翻译内容改编自如何在JavaScript中预加载多张图片的最佳方法?:
使用new Image()
不会涉及使用DOM方法的开销,但是指定图像的新请求将被添加到队列中。此时,由于该图像实际上未添加到页面中,因此没有涉及重新渲染。然而,我建议将其添加到页面末尾(当可能时,所有脚本都应该放在末尾),以防止它阻止更关键的元素。
编辑:根据评论的正确指出,需要使用单独的Image
对象才能正常工作。感谢您的指正,并对我没有仔细检查表示歉意。
编辑2:为了更明显地表明可重复使用性,进行了编辑。
编辑3(三年后):
由于浏览器处理非可见图片的方式发生了变化(display: none或者从未添加到文档中,如本答案所示),现在推荐使用一种新的预加载方法。例如,您可以使用Ajax请求来强制提前检索图像。使用jQuery:
jQuery.get(source);
或者在我们之前的例子中,你可以这样做:
function preload(sources)
{
jQuery.each(sources, function(i,source) { jQuery.get(source); });
}
请注意,这不适用于精灵图这种情况,因为它们已经很好了。这只适用于像照片库或带有图片的滑块/轮播等内容的情况,其中图片由于最初不可见而未加载。精灵图
正如其他人所提到的,精灵图在许多方面都非常有效,但它并没有被描述得那么好。
然而处理不规则形状的图像比较棘手。将所有新图像合并成一个新图像还是有点麻烦。
使用<img>标签的低侵入性方法
如果您正在寻找最可靠的解决方案,则应选择我仍然更喜欢的低侵入性方法。在文档末尾创建指向图片的<img>链接,并将其width
和height
设置为1x1像素,并将它们放在隐藏的div中。如果它们在页面底部,它们将在其他内容之后加载。
截至2013年1月,这里描述的方法都无法为我所用,所以这是我做的,经过测试并在Chrome 25和Firefox 18中有效。使用jQuery和此插件来解决加载事件的问题:
function preload(sources, callback) {
if(sources.length) {
var preloaderDiv = $('<div style="display: none;"></div>').prependTo(document.body);
$.each(sources, function(i,source) {
$("<img/>").attr("src", source).appendTo(preloaderDiv);
if(i == (sources.length-1)) {
$(preloaderDiv).imagesLoaded(function() {
$(this).remove();
if(callback) callback();
});
}
});
} else {
if(callback) callback();
}
}
使用方法:
preload(['/img/a.png', '/img/b.png', '/img/c.png'], function() {
console.log("done");
});
我认为,在未来几年中,使用一些库引入的Multipart XMLHttpRequest 将是首选解决方案。但是IE版本< v8仍然不支持data:uri(即使IE8有限制,最多允许32kb)。这里是并行图片预加载的实现-http://code.google.com/p/core-framework/wiki/ImagePreloading ,它捆绑在框架中,但仍值得一看。
#hidden_preload {
height: 1px;
left: -20000px;
position: absolute;
top: -20000px;
width: 1px;
}
以下是我的简单解决方案,图像加载后淡入效果。
function preloadImage(_imgUrl, _container){
var image = new Image();
image.src = _imgUrl;
image.onload = function(){
$(_container).fadeTo(500, 1);
};
}
针对我的使用情况,我有一个带有全屏图像的轮播图,我想要预加载它们。然而,由于这些图像按顺序显示,并且每个图像可能需要几秒钟才能加载完成,因此按顺序、连续地加载它们非常重要。
为此,我使用了async库的waterfall()
方法(https://github.com/caolan/async#waterfall)。
// Preload all images in the carousel in order.
image_preload_array = [];
$('div.carousel-image').each(function(){
var url = $(this).data('image-url');
image_preload_array.push(function(callback) {
var $img = $('<img/>')
$img.load(function() {
callback(null);
})[0].src = url;
});
});
async.waterfall(image_preload_array);
这个方法通过创建一个函数数组来实现,每个函数都会传递参数callback()
,以便执行下一个函数。 callback()
的第一个参数是错误消息,如果提供了非空值,则会退出序列,因此我们每次都传递null。