当前位置:  开发笔记 > 编程语言 > 正文

使用jQuery预加载图像

如何解决《使用jQuery预加载图像》经验,为你挑选了11个好方法。

我正在寻找一种使用JavaScript预加载图像的快捷方法.我正在使用jQuery,如果这很重要的话.

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

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

但是,它看起来有点过头了我想要的东西!

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



1> James..:

快速简单的:

function preload(arrayOfImages) {
    $(arrayOfImages).each(function(){
        $('')[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(){
        $('')[0].src = this;
    });
}

// Usage:

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


这是编写jQuery插件的一种奇怪方式.为什么不`$ .preload(['img1.jpg','img2.jpg'])``
是不是需要将图像元素插入到DOM中以确保浏览器缓存它?
确保在`$(window).load(function(){/*preload here*/})中调用它;`因为这样首先加载文档中的所有图像,所以可能首先需要它们.
@RegionalC - 在设置`src`之前设置`load`事件可能会更安全一些,以防图像在设置加载事件之前完成加载?`$('').load(function(){/*它已加载!*/}).attr('src',this);`
我相信`$('')`只是在内存中创建一个图像元素(参见[link](http://api.jquery.com/jQuery/#jQuery2)).它看起来像`'$('')`实际上会在隐藏的DIV中创建元素,因为它更"复杂".但是,我认为大多数浏览器都不需要这样做.
根据我刚刚做的以下jsfiddle实验,这个答案是完全有效的.即使没有将图像添加到文档中,也会为图像触发加载事件...但是,您可能还希望包含一个在加载事件上执行的函数,以便在加载图像后对图像执行某些操作.http://jsfiddle.net/2cgFp/6/
仅供参考:`$(document.createElement('img'))`虽然比较详细,但比`$('')稍快,因为jQuery不必解析字符串并弄清楚它是否是一个字符串选择器或要创建的元素.
但是,如何检测所有预加载何时完成?
我猜内部`$('')`使用`(new Image())`为什么要将它作为替代?是否存在不起作用的情况?

2> Dennis Rongo..:

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

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


`hide()`比`css('display','none')更简洁.
根据我的经验,将图像预加载到DOM中会使浏览器意识到它的存在并使其正确缓存.否则,图像仅存在于仅适用于单页应用程序的内存中.
将它们插入DOM有什么好处?

3> Gajus..:

使用JavaScript Image对象.

此功能允许您在加载所有图片时触发回调.但请注意,如果未加载至少一个资源,它将永远不会触发回调.这可以通过实现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');
});


*做正确的事,使用JavaScript Image对象.*你是否观察到人们在这些答案中做了*错误的事情?
@alex可能,是的.如果目标是预加载(这表明性能的顺序),那么我更愿意看到原始JS选项而不是jQuery依赖选项.

4> Dave..:

JP,在检查了你的解决方案之后,我仍然在Firefox中遇到问题,在加载页面之前它不会预先加载图像.我sleep(5)在服务器端脚本中添加了一些内容.我实现了以下基于你的解决方案,似乎解决了这个问题.

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

// 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() {
    $('').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调用上预加载图像的解决方案.


一切都会好的,但是在你不拥有的对象中添加新的或删除现有的方法是JavaScript中最糟糕的做法之一.
对于那些对搞乱Array.prototype不感兴趣的人,你可以这样做:`checklist = this.length`并在onload函数中:`checklist - `then:`if(checklist == 0)callback( );`

5> rkcell..:

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

$('');


@huzzah - 你可能最好只使用精灵.减少http请求.:)

6> yckart..:
$.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/



7> alex..:

我有一个小插件来处理这个问题.

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

如果您只是想加载所有图像,包括CSS中引用的图像,以下是您将如何做到这一点:)

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



8> alzclarke..:

这个jquery imageLoader插件只有1.39kb

用法:

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

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


错误地使用$(document).ready在回调中:|
@AamirAfridi对于这种情况没有任何意义.该插件是一个**pre**加载器.你想尽快执行它.并且有很多东西不依赖于你想要尽快解雇的DOM,**然后**当DOM准备就绪时,做一些事情.

9> itsme..:

你可以使用css display:none;规则在你的html中加载图像,然后用js或jquery显示它们

不要使用js或jquery函数来预加载只是一个css规则与许多js行要执行

例如:Html


CSS:

.hide{
display:none;
}

jQuery的:

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

通过jquery/javascript预加载图像并不好,因为图像在页面加载需要几毫秒才能解析和执行脚本,特别是如果它们是大图像,那么将它们隐藏在hml中对性能来说也更好因为图像真的是预先加载而根本没有看到,直到你显示出来!


但是你需要知道这种技术有一个主要缺点:在加载所有图像之前,你的页面不会被完全加载.根据要预加载的图像数量及其大小,这可能需要一些时间.更糟糕的是,如果标签没有指定高度和宽度,某些浏览器可能会等到呈现图像之后再渲染页面的其余部分.
有关此方法的更多信息,请访问:http://perishablepress.com/-way-to-preload-images-without-javascript-that-is-so-much-better/

10> izb..:

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

function preload(files, cb) {
    var len = files.length;
    $(files.map(function(f) {
        return '';
    }).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 '';
    }).join('')).load(function () {
        if(--len===0) {
            cb();
        }
    });
}



11> dgig..:

谢谢你!我会在JP的答案上加上一点点riff - 我不知道这是否会对任何人有所帮助,但是这样你就不必创建一个图像数组了,你可以预先加载你所有的大图像正确命名你的拇指.这很方便,因为我有一个人正在用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.拇指向大只用_lg.jpg替换_th.jpg然后预加载所有大图像.

希望这有助于某人.

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有