使用jQuery预加载图像

我正在寻找一种使用JavaScript预加载图像的快速简便方法。如果这很重要,我正在使用jQuery。

我在这里看到了这个(http://nettuts.com.…):

function complexLoad(config, fileNames) {
for (var x = 0; x < fileNames.length; x++) {
$("<img>").attr({
id: fileNames[x],
src: config.imgDir + fileNames[x] + config.imgFormat,
title: "The " + fileNames[x] + " nebula"
}).appendTo("#" + config.imgContainer).css({ display: "none" });
}
};

但是,对于我想要的东西来说,它看起来有点过分了!

我知道有一些jQuery插件可以做到这一点,但它们看起来都有点大(大小);我只需要一个快速、简单和简短的预加载图像的方法!

484554 次浏览

快速简单:

function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}


// Usage:


preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);

或者,如果你想要一个jQuery插件:

$.fn.preload = function() {
this.each(function(){
$('<img/>')[0].src = this;
});
}


// Usage:


$(['img1.jpg','img2.jpg','img3.jpg']).preload();

JP,在检查了你的解决方案之后,我在Firefox中仍然遇到问题,它不会在加载页面之前预加载图像。我通过在我的服务器端脚本中放一些sleep(5)来发现这一点。我根据你的解决方案实现了以下解决方案,似乎解决了这个问题。

基本上,我给你的jQuery预加载插件添加了一个回调,以便在所有图像正确加载后调用它。

// Helper function, used below.
// Usage: ['img1.jpg','img2.jpg'].remove('img1.jpg');
Array.prototype.remove = function(element) {
for (var i = 0; i < this.length; i++) {
if (this[i] == element) { this.splice(i,1); }
}
};


// Usage: $(['img1.jpg','img2.jpg']).preloadImages(function(){ ... });
// Callback function gets called after all images are preloaded
$.fn.preloadImages = function(callback) {
checklist = this.toArray();
this.each(function() {
$('<img>').attr({ src: this }).load(function() {
checklist.remove($(this).attr('src'));
if (checklist.length == 0) { callback(); }
});
});
};

出于兴趣,在我的上下文中,我使用如下:

$.post('/submit_stuff', { id: 123 }, function(response) {
$([response.imgsrc1, response.imgsrc2]).preloadImages(function(){
// Update page with response data
});
});

希望这能帮助那些从Google来到这个页面的人(就像我一样)寻找在Ajax调用上预加载图像的解决方案。

这个jQuery图片加载器插件只有1.39kb

用法:

$({}).imageLoader({
images: [src1,src2,src3...],
allcomplete:function(e,ui){
//images are ready here
//your code - site.fadeIn() or something like that
}
});

还有其他选项,例如您是要同步还是异步加载图像,以及每个单独图像的完整事件。

我有一个小插件可以处理这个问题。

它被称为等待获取图片,它可以处理img元素或任何引用CSS中图像的元素,例如div { background: url(img.png) }

如果你只是想加载所有图像,包括CSS中引用的图像,以下是你的操作方式:)

$('body').waitForImages({
waitForAll: true,
finished: function() {
// All images have loaded.
}
});

谢谢!我想在J-P的回答上添加一点重复——我不知道这是否对任何人都有帮助,但这样你就不必创建一个图像数组,如果你正确地命名你的拇指,你可以预加载所有的大图像。这很方便,因为我有一个人用html编写所有的页面,这确保了他们少了一步——消除了创建图像数组的需要,还有一个步骤可能会搞砸。

$("img").each(function(){
var imgsrc = $(this).attr('src');
if(imgsrc.match('_th.jpg') || imgsrc.match('_home.jpg')){
imgsrc = thumbToLarge(imgsrc);
(new Image()).src = imgsrc;
}
});

基本上,对于页面上的每个图像,它会获取每个图像的src,如果它符合某些条件(是拇指或主页图像),它会更改名称(图像src中的基本字符串替换),然后加载图像。

在我的例子中,页面上充满了拇指图像,所有这些图像都被命名为image_th.jpg,所有相应的大图像都被命名为image_lg.jpg.拇指变大只是将_th.jpg替换为_lg.jpg,然后预加载所有的大图像。

希望这有助于某人。

这是第一个响应的调整版本,它实际上将图像加载到DOM中并默认隐藏它。

function preload(arrayOfImages) {
$(arrayOfImages).each(function () {
$('<img />').attr('src',this).appendTo('body').css('display','none');
});
}

这一行jQuery代码创建(并加载)一个DOM元素img而不显示它:

$('<img src="img/1.jpg"/>');

您可以使用cssdisplay:none;规则在html中的某个地方加载图像,然后在需要时使用js或jQuery显示它们

不使用js或者jQuery函数预加载只是一条css规则VS很多行js要执行

示例:Html

<img src="someimg.png" class="hide" alt=""/>

css:

.hide{
display:none;
}

jQuery:

//if want to show img
$('.hide').show();
//if want to hide
$('.hide').hide();

通过jQuery/javascript预加载图像不好,因为图像在页面中加载需要几毫秒+你有毫秒的脚本来解析和执行,特别是如果它们是大图像,所以将它们隐藏在hml中对性能也更好,因为图像实际上是预加载的,根本不可见,直到你显示出来!

function preload(imgs) {
$(imgs).each(function(index, value) {
$('<img />').attr('src', value).appendTo('body').css('display', 'none');
});
}

.attr('src',value) 没有 .attr('src',this)

只是指出来:)

在jQuery中预加载图像并获得回调函数的一种快速、无插件的方法是一次创建多个img标签并计算响应,例如:

function preload(files, cb) {
var len = files.length;
$(files.map(function(f) {
return '<img src="'+f+'" />';
}).join('')).load(function () {
if(--len===0) {
cb();
}
});
}


preload(["one.jpg", "two.png", "three.png"], function() {
/* Code here is called once all files are loaded. */
});
​    ​

请注意,如果你想支持IE7,你需要使用这个稍微不那么漂亮的版本(它也适用于其他浏览器):

function preload(files, cb) {
var len = files.length;
$($.map(files, function(f) {
return '<img src="'+f+'" />';
}).join('')).load(function () {
if(--len===0) {
cb();
}
});
}

使用JavaScript图像对象

此函数允许您在加载所有图片时触发回调。但是,请注意,如果至少有一个资源未加载,它将永远不会触发回调。这可以通过实现onerror回调并递增loaded值或处理错误来轻松修复。

var preloadPictures = function(pictureUrls, callback) {
var i,
j,
loaded = 0;


for (i = 0, j = pictureUrls.length; i < j; i++) {
(function (img, src) {
img.onload = function () {
if (++loaded == pictureUrls.length && callback) {
callback();
}
};


// Use the following callback methods to debug
// in case of an unexpected behavior.
img.onerror = function () {};
img.onabort = function () {};


img.src = src;
} (new Image(), pictureUrls[i]));
}
};


preloadPictures(['http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar'], function(){
console.log('a');
});


preloadPictures(['http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar'], function(){
console.log('b');
});

这对我来说甚至在IE9中也有效:

$('<img src="' + imgURL + '"/>').on('load', function(){ doOnLoadStuff(); });
    jQuery.preloadImage=function(src,onSuccess,onError)
{
var img = new Image()
img.src=src;
var error=false;
img.onerror=function(){
error=true;
if(onError)onError.call(img);
}
if(error==false)
setTimeout(function(){
if(img.height>0&&img.width>0){
if(onSuccess)onSuccess.call(img);
return img;
}   else {
setTimeout(arguments.callee,5);
}
},0);
return img;
}


jQuery.preloadImages=function(arrayOfImages){
jQuery.each(arrayOfImages,function(){
jQuery.preloadImage(this);
})
}
// example
jQuery.preloadImage(
'img/someimage.jpg',
function(){
/*complete
this.width!=0 == true
*/
},
function(){
/*error*/
}
)
$.fn.preload = function (callback) {
var length = this.length;
var iterator = 0;


return this.each(function () {
var self = this;
var tmp = new Image();


if (callback) tmp.onload = function () {
callback.call(self, 100 * ++iterator / length, iterator === length);
};


tmp.src = this.src;
});
};

用法很简单:

$('img').preload(function(perc, done) {
console.log(this, perc, done);
});

http://jsfiddle.net/yckart/ACbTK/

我使用以下代码:

$("#myImage").attr("src","img/spinner.gif");


var img = new Image();
$(img).load(function() {
$("#myImage").attr("src",img.src);
});
img.src = "http://example.com/imageToPreload.jpg";

我想用谷歌地图API自定义覆盖来做到这一点。他们的示例代码简单地使用JS插入IMG元素,并显示图像占位符框,直到图像加载。我在这里找到了一个对我有用的答案:https://stackoverflow.com/a/10863680/2095698

$('<img src="'+ imgPaht +'">').load(function() {
$(this).width(some).height(some).appendTo('#some_target');
});

这预加载图像建议之前,然后使用处理程序加载img URL后的img对象. jQuery的留档警告,缓存的图像不工作与此事件/处理程序代码,但它的工作为我在FireFox和Chrome,我不必担心IE。

5行咖啡

array = ['/img/movie1.png','/img/movie2.png','/img/movie3.png']


$(document).ready ->
for index, image of array
img[index] = new Image()
img[index].src = image

我会使用一个清单文件来告诉(现代)Web浏览器也加载所有相关图像并缓存它们。使用Grunt和grunt-清单自动执行此操作,再也不用担心预加载脚本、缓存无效器、CDN等。

对于那些知道一点actioncript的人,您可以轻松检查flash播放器,并制作一个flash预加载器,您也可以导出到html5/Javascript/JQuery。 如果未检测到Flash播放器,请查看有关如何使用youtube角色返回html5播放器的示例:) 创造你自己的。 我没有详细信息,因为我还没有开始,如果我没有忘记,我会稍后发布,并尝试一些standerd JQuery代码来我的。

我通常在我的项目中使用这段代码片段来加载页面中的图像。 你可以在这里看到结果https://jsfiddle.net/ftor34ey/

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>


<img src="https://live.staticflickr.com/65535/50020763321_d61d49e505_k_d.jpg" width="100" />
<img src="https://live.staticflickr.com/65535/50021019427_692a8167e9_k_d.jpg" width="100" />
<img src="https://live.staticflickr.com/65535/50020228418_d730efe386_k_d.jpg" width="100" />
<img src="https://live.staticflickr.com/65535/50020230828_7ef175d07c_k_d.jpg" width="100" />


<div style="background-image: url(https://live.staticflickr.com/65535/50020765826_e8da0aacca_k_d.jpg);"></div>
<style>
.bg {
background-image: url("https://live.staticflickr.com/65535/50020765651_af0962c22e_k_d.jpg");
}
</style>
<div class="bg"></div>


<div id="loadingProgress"></div>

该脚本将页面的所有srcbackground-image保存在一个数组中并加载它们。

您可以通过varloadCount查看/读取/显示加载进度。

let backgroundImageArray = [];


function backgroundLoading(i) {


let loadCount = 0;


let img = new Image();
$(img).on('load', function () {


if (i < backgroundImageArray.length) {


loadCount = parseInt(((100 / backgroundImageArray.length) * i));
backgroundLoading(i + 1);


} else {


loadCount = 100;
// do something when the page finished to load all the images
console.log('loading completed!!!');
$('#loadingProgress').append('<div>loading completed!!!</div>');


}


console.log(loadCount + '%');
$('#loadingProgress').append('<div>' + loadCount + '%</div>');


}).attr('src', backgroundImageArray[i - 1]);


}


$(document).ready(function () {


$('*').each(function () {


var backgroundImage = $(this).css('background-image');
var putInArray = false;


var check = backgroundImage.substr(0, 3);


if (check == 'url') {


backgroundImage = backgroundImage.split('url(').join('').split(')').join('');
backgroundImage = backgroundImage.replace('"', '');
backgroundImage = backgroundImage.replace('"', '');


if (backgroundImage.substr(0, 4) == 'http') {
backgroundImage = backgroundImage;
}
putInArray = true;


} else if ($(this).get(0).tagName == 'IMG') {


backgroundImage = $(this).attr('src');
putInArray = true;


}


if (putInArray) {
backgroundImageArray[backgroundImageArray.length] = backgroundImage;
}


});


backgroundLoading(1);


});