665 votes

Moyen officiel de demander à jQuery d'attendre le chargement de toutes les images avant d'exécuter quelque chose.

Dans jQuery, quand vous faites ça :

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

Il attend que le DOM se charge et exécute votre code. Si toutes les images ne sont pas chargées, elle exécute quand même le code. C'est évidemment ce que nous voulons si nous initialisons un élément du DOM, comme afficher ou cacher des éléments ou attacher des événements.

Disons que je veux une animation et que je ne veux pas qu'elle soit lancée avant que toutes les images soient chargées. Existe-t-il un moyen officiel de faire cela dans jQuery ?

Le meilleur moyen que j'ai trouvé est d'utiliser <body onload="finished()"> mais je ne veux pas vraiment faire ça à moins d'y être obligé.

Remarque : Il existe un bogue dans jQuery 1.3.1 dans Internet Explorer qui attend en fait que toutes les images soient chargées avant d'exécuter le code à l'intérieur $function() { } . Ainsi, si vous utilisez cette plateforme, vous obtiendrez le comportement que je recherche au lieu du comportement correct décrit ci-dessus.

3 votes

N'a pas $("img").load() travail ?

1 votes

Je pense qu'il est utile de mentionner que si vous définissez les attributs de dimensions, vous pouvez exécuter en toute sécurité du code dans la fonction prête qui repose sur ces dimensions. Avec php, vous pouvez les saisir avec php.net/manual/fr/function.getimagesize.php lors du téléchargement pour les stocker dans la base de données ou avant la sortie vers le navigateur.

0 votes

Si vous voulez quelque chose qui fasse un travail incroyable, alors consultez la très bonne et populaire bibliothèque javascript imagesloaded mentionnée dans la réponse ci-dessous. stackoverflow.com/a/26458347/759452

1065voto

paxdiablo Points 341644

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

La différence peut être vue dans le fichier HTML complet suivant, à condition que vous ayez beaucoup de jollyrogerNN Fichiers JPEG (ou 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 in total
        <img src="jollyroger99.jpg">
    </body>
</html>

Ainsi, la boîte d'alerte apparaît avant que les images ne soient chargées, car le DOM est prêt à ce moment-là. Si vous changez ensuite :

$(document).ready(function() {

dans :

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

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

Ainsi, pour attendre que la page entière soit prête, vous pourriez utiliser quelque chose comme :

$(window).on("load", function() {
    // weave your magic here.
});

32 votes

claque le front +J'ai totalement oublié ça. $(window).load() ne se déclenchera pas tant que les images ne seront pas terminées.

0 votes

Merci ! ça a marché. je n'avais pas vraiment remarqué à quel point l'effet était mauvais jusqu'à ce que je le teste localement dans Safari sous Windows. ensuite, il m'est apparu douloureusement évident que je devais le faire. claques sur le front

0 votes

Sauf que vous n'avez pas besoin de l'attente. il suffit de mettre la logique dans load(..). c'est ce que vous vouliez dire par "se frapper le front" ?

159voto

alex Points 186293

J'ai écrit un plugin qui peut déclencher des callbacks lorsque des images ont été chargées dans des éléments, ou déclencher une fois par image chargée.

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

Il prend également en charge le chargement des images référencées dans le CSS, telles que background-image , list-style-image etc.

plugin jQuery waitForImages

Exemple d'utilisation

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

Exemple sur jsFiddle .

Plus de documentation est disponible sur la page GitHub.

1 votes

Merci ! $.load() ne fonctionnait pas pour moi, mais ceci fait parfaitement l'affaire.

0 votes

J'utilise Chrome Version 22.0.1229.94 et ce plugin, et j'ai essayé de lire les décalages des images chargées dans le waitFormImages : ('img selector').each(function(index) { var offset = $(this).offset(); ...}); Cependant, offset.top est toujours égal à zéro. Pourquoi ?

1 votes

@basZero Difficile à dire sans plus de contexte. Veuillez soulever un problème sur la page Questions page.

48voto

Hristo Yankov Points 721

$(window).load() ne fonctionnera que la première fois que la page sera chargée. Si vous faites des choses dynamiques (exemple : cliquer sur un bouton, attendre le chargement de nouvelles images), cela ne fonctionnera pas. Pour cela, 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);

0 votes

Juste au cas où quelqu'un aurait besoin d'un exemple d'utilisation du plugin BatchImagesLoad : yankov.us/batchImageLoad

1 votes

Je ne veux pas vous manquer de respect, mais on ne peut pas se fier "uniquement" à votre parole concernant la fiabilité de votre plugin. Comme mentionné dans Yevgeniy Afanasyev Réponse de la Commission imagesLoaded fait un bien meilleur travail à cet égard et couvre le cas d'utilisation que vous avez mentionné ainsi que de nombreux autres cas particuliers. (voir les problèmes résolus sur github) .

19voto

leo-the-manic Points 1145

Pour ceux qui veulent être informés de la fin du téléchargement d'une seule image, demandée après l'envoi d'une demande d'accès à l'Internet. $(window).load vous pouvez utiliser l'élément d'image load événement.

par exemple :

// 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");
});

4voto

molokoloco Points 1626

Avec jQuery je viens avec ce...

$(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/

0 votes

J'ai découvert que cela ne fonctionnera pas correctement si le navigateur renvoie une réponse 304 Not Mofified pour l'image, ce qui signifie que l'image est mise en cache.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X