Façon officielle de demander à jQuery d'attendre que toutes les images se chargent avant d'exécuter quelque chose

En jQuery lorsque vous faites cela:

$(function() {
   alert("DOM is loaded, but images not necessarily all loaded");
});

il attend que le DOM charge et exécute votre code. Si toutes les images ne sont pas chargées, le code est quand même exécuté. C'est évidemment ce que nous voulons si nous initialisons quelque chose de DOM comme Montrer ou cacher des éléments ou attacher des événements.

disons que je veux un peu d'animation et que je ne veux pas qu'elle tourne tant que toutes les images ne sont pas chargées. Y a-t-il un moyen officiel à jQuery pour faire cela?

la meilleure façon que j'ai est d'utiliser <body onload="finished()"> , mais je ne veux pas vraiment le faire à moins que je dois le faire.

Note: il y a un bug dans jQuery 1.3.1 dans Internet Explorer qui attend en fait que toutes les images se chargent avant d'exécuter le code à l'intérieur de $function() { } . Donc, si vous utilisez cette plateforme, vous obtiendrez le comportement que je recherche au lieu du comportement correct décrit ci-dessus.

603
demandé sur Community 2009-02-13 09:56:25

10 réponses

avec jQuery, vous utilisez $(document).ready() pour exécuter quelque chose quand le DOM est chargé et $(window).on("load", handler) pour exécuter quelque chose quand toutes les autres choses sont chargées aussi bien, comme les images.

la différence peut être vue dans le fichier HTML complet suivant, à condition que vous ayez un fichier jollyroger JPEG (ou d'autres fichiers appropriés):

<html>
    <head>
        <script src="jquery-1.7.1.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                alert ("done");
            });
        </script>
    </head><body>
        Hello
        <img src="jollyroger00.jpg">
        <img src="jollyroger01.jpg">
        // : 100 copies of this
        <img src="jollyroger99.jpg">
    </body>
</html>

avec cela, la boîte d'alerte apparaît avant le chargement des images, car le DOM est prêt à ce point. Si vous changez alors:

$(document).ready(function() {

dans:

$(window).on("load", function() {

puis la boîte d'alerte n'apparaît pas avant après les images sont chargées.

donc, pour attendre que toute la page soit prête, vous pouvez utiliser quelque chose comme:

$(window).on("load", function() {
    // weave your magic here.
});
989
répondu paxdiablo 2016-10-01 20:16:21

j'ai écrit un plugin qui peut lancer des callbacks lorsque les images ont été chargées dans des éléments, ou tirer une fois par image chargée.

Il est semblable à $(window).load(function() { .. }) , sauf qu'il vous permet de définir n'importe quel sélecteur à vérifier. Si vous voulez savoir quand toutes les images dans #content (par exemple) ont chargé, c'est le plugin pour vous.

il supporte également le chargement d'images référencées dans le CSS, telles que background-image , list-style-image , etc.

waitforimages jQuery plugin

Exemple D'Usage

$('selector').waitForImages(function() {
    alert('All images are loaded.');
});

exemple sur jsFiddle .

plus de documentation disponible sur la page GitHub.

153
répondu alex 2016-02-22 10:12:15

$(window).load() fonctionne uniquement la première fois que la page est chargée. Si vous faites des choses dynamiques (exemple: cliquez sur le bouton, attendez que de nouvelles images se chargent), cela ne marchera pas. Pour ce faire, vous pouvez utiliser mon plugin:

Démo

télécharger

/**
 *  Plugin which is applied on a list of img objects and calls
 *  the specified callback function, only when all of them are loaded (or errored).
 *  @author:  H. Yankov (hristo.yankov at gmail dot com)
 *  @version: 1.0.0 (Feb/22/2010)
 *  http://yankov.us
 */

(function($) {
$.fn.batchImageLoad = function(options) {
    var images = $(this);
    var originalTotalImagesCount = images.size();
    var totalImagesCount = originalTotalImagesCount;
    var elementsLoaded = 0;

    // Init
    $.fn.batchImageLoad.defaults = {
        loadingCompleteCallback: null, 
        imageLoadedCallback: null
    }
    var opts = $.extend({}, $.fn.batchImageLoad.defaults, options);

    // Start
    images.each(function() {
        // The image has already been loaded (cached)
        if ($(this)[0].complete) {
            totalImagesCount--;
            if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);
        // The image is loading, so attach the listener
        } else {
            $(this).load(function() {
                elementsLoaded++;

                if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);

                // An image has been loaded
                if (elementsLoaded >= totalImagesCount)
                    if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
            });
            $(this).error(function() {
                elementsLoaded++;

                if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);

                // The image has errored
                if (elementsLoaded >= totalImagesCount)
                    if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
            });
        }
    });

    // There are no unloaded images
    if (totalImagesCount <= 0)
        if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
};
})(jQuery);
48
répondu Roko C. Buljan 2015-12-15 19:56:12

pour ceux qui veulent être informés de l'achèvement du téléchargement d'une seule image qui est demandée après $(window).load incendies, vous pouvez utiliser l'événement load de l'élément d'image.

p.ex.:

// create a dialog box with an embedded image
var $dialog = $("<div><img src='" + img_url + "' /></div>");

// get the image element (as a jQuery object)
var $imgElement = $dialog.find("img");

// wait for the image to load 
$imgElement.load(function() {
    alert("The image has loaded; width: " + $imgElement.width() + "px");
});
19
répondu Dan Passaro 2015-01-18 00:07:31

aucune des réponses jusqu'à présent n'a donné ce qui semble être la solution la plus simple.

$('#image_id').load(
  function () {
    //code here
});
8
répondu Coz 2016-10-23 21:17:19

je recommande l'utilisation de imagesLoaded.js bibliothèque javascript.

pourquoi ne pas utiliser le $(window).load() de jQuery ?

comme répondu sur https://stackoverflow.com/questions/26927575/why-use-imagesloaded-javascript-library-versus-jquerys-window-load/26929951

C'est une question de portée. imagesload vous permet de cibler un ensemble d'images, alors que $(window).load() cible tous les actifs - y compris toutes les images, objets, .js et .fichiers css, et même iframes. Très probablement, imagesload déclenchera plus tôt que $(window).load() parce qu'il vise un plus petit ensemble d'actifs.

autres bonnes raisons d'utiliser imagesloaded

  • officiellement soutenu par IE8+
  • licence: MIT licence
  • dépendances: aucune
  • poids (minifiés et gzippé) : 7kb minimisé (la lumière!)
  • download builder (aide à réduire le poids): pas besoin, déjà minuscule
  • sur Github: Oui
  • "1519210920 de" communauté et contributeurs : assez grande, plus de 4000 membres, bien que seulement 13 contributeurs
  • histoire et contributions : stable comme relativement ancienne (depuis 2010), mais toujours actif projet

ressources

5
répondu Adrien Be 2017-05-23 11:47:32

avec jQuery je viens avec ceci...

$(function() {
    var $img = $('img'),
        totalImg = $img.length;

    var waitImgDone = function() {
        totalImg--;
        if (!totalImg) alert("Images loaded!");
    };

    $('img').each(function() {
        $(this)
            .load(waitImgDone)
            .error(waitImgDone);
    });
});

Démo: http://jsfiddle.net/molokoloco/NWjDb /

4
répondu molokoloco 2017-09-06 10:23:11

utiliser imagesLoaded PACKAGED v3.1.8 (6.8 Kb when minimized). Il s'agit d'un projet relativement ancien (depuis 2010) mais toujours actif.

Vous pouvez le trouver sur github: https://github.com/desandro/imagesloaded

leur site officiel: http://imagesloaded.desandro.com /

Pourquoi c'est mieux que d'utiliser:

$(window).load() 

parce que vous pouvez vouloir charger des images dynamiquement, comme ceci: jsfiddle

$('#button').click(function(){
    $('#image').attr('src', '...');
});
1
répondu Yevgeniy Afanasyev 2014-11-19 00:34:45

de cette façon, vous pouvez exécuter une action lorsque toutes les images à l'intérieur du corps ou tout autre conteneur (qui dépend de votre sélection) sont chargés. Pur JQUERY, pas besoin de plugins.

var counter = 0;
var size = $('img').length;

$("img").load(function() { // many or just one image(w) inside body or any other container
    counter += 1;
    counter === size && $('body').css('background-color', '#fffaaa'); // any action
}).each(function() {
  this.complete && $(this).load();        
});
1
répondu Mario Medrano 2016-04-01 19:25:31

ma solution est similaire à molokoloco . Écrit comme la fonction jQuery:

$.fn.waitForImages = function (callback) {
    var $img = $('img', this),
        totalImg = $img.length;

    var waitImgLoad = function () {
        totalImg--;
        if (!totalImg) {
            callback();
        }
    };

    $img.each(function () {
        if (this.complete) { 
            waitImgLoad();
        }
    })

    $img.load(waitImgLoad)
        .error(waitImgLoad);
};

exemple:

<div>
    <img src="img1.png"/>
    <img src="img2.png"/>
</div>
<script>
    $('div').waitForImages(function () {
        console.log('img loaded');
    });
</script>
0
répondu Mariusz Charczuk 2018-03-30 05:26:45