Официальный способ спросить jQuery ждать загрузки всех изображений перед выполнением чего-либо

В jQuery, когда вы это делаете:

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

Он ожидает, что DOM загрузит и выполнит ваш код. Если все изображения не загружены, он все равно выполняет код. Это, очевидно, то, что мы хотим, если мы инициализируем любые вещи DOM, такие как отображение или скрытие элементов или добавление событий.

Скажем, хотя мне нужна анимация, и я не хочу, чтобы она работала до загрузки всех изображений. Есть ли официальный способ в jQuery для этого?

Лучше всего использовать <body onload="finished()">, но я действительно не хочу этого делать, если не нужно.

Примечание. В Internet Explorer есть ошибка в jQuery 1.3.1, которая фактически ожидает загрузки всех изображений перед выполнением кода внутри $function() { }. Поэтому, если вы используете эту платформу, вы получите поведение, которое я ищу, вместо правильного поведения, описанного выше.

Ответ 1

С помощью jQuery вы используете $(document).ready() для выполнения чего-либо при загрузке DOM и $(window).on("load", handler) для выполнения чего-либо, когда загружаются все другие вещи, например изображения.

Разницу можно увидеть в следующем полном файле HTML, если у вас есть файлы jollyroger JPEG (или другие подходящие):

<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>

При этом перед загрузкой изображений появляется окно предупреждения, поскольку DOM готов к этой точке. Если вы затем измените:

$(document).ready(function() {

в

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

тогда окно предупреждения не появится до загрузки изображений.

Следовательно, чтобы подождать, пока вся страница будет готова, вы можете использовать что-то вроде:

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

Ответ 2

Я написал плагин, который может запускать обратные вызовы, когда изображения загружаются в элементы, или запускать один раз на загруженное изображение.

Он похож на $(window).load(function() { .. }), за исключением того, что он позволяет определить любой селектор для проверки. Если вы хотите знать, когда загрузились все изображения в #content (например), это плагин для вас.

Он также поддерживает загрузку изображений, указанных в CSS, таких как background-image, list-style-image и т.д.

waitForImages Плагин jQuery

Пример использования

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

Пример jsFiddle.

Дополнительная документация доступна на странице GitHub.

Ответ 3

$(window).load() будет работать только при первой загрузке страницы. Если вы делаете динамический материал (например: нажмите кнопку, дождитесь загрузки некоторых новых изображений), это не сработает. Для этого вы можете использовать мой плагин:

Демо

Загрузить

/**
 *  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);

Ответ 4

Для тех, кто хочет получить уведомление о завершении загрузки одного изображения, которое запрашивается после срабатывания $(window).load, вы можете использовать событие load элемента изображения.

например:.

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

Ответ 5

Ни один из ответов до сих пор не дал то, что кажется самым простым решением.

$('#image_id').load(
  function () {
    //code here
});

Ответ 6

Я бы рекомендовал использовать библиотеку javascript imagesLoaded.js.

Почему бы не использовать jQuery $(window).load()?

Как обсуждалось на https://stackoverflow.com/questions/26927575/why-use-imagesloaded-javascript-library-versus-jquerys-window-load/26929951

Это вопрос сферы. imagesLoaded позволяет вам настроить набор изображений, тогда как $(window).load() нацеливает все активы, включая все изображения, объекты,.js и .css файлы и даже iframe. Скорее всего, imagesLoaded будет срабатывать раньше, чем $(window).load(), потому что он нацелен на меньший набор активов.

Другие веские причины использовать загруженные изображения

  • официально поддерживается IE8 +
  • лицензия: лицензия MIT
  • зависимости: none
  • вес (minified и gzipped): 7kb minified (свет!)
  • скачать строитель (помогает сократить вес): нет необходимости, уже крошечный
  • в Github: YES
  • сообщество и участники: довольно большой, 4000+ участников, хотя только 13 участников
  • история и вклад: стабильный как относительно старый (с 2010 года), но все еще активный проект

Ресурсы

Ответ 7

С jQuery я прихожу с этим...

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

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

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

Демо: http://jsfiddle.net/molokoloco/NWjDb/

Ответ 8

Использовать imagesLoaded PACKAGED v3.1.8 (6.8 Kb при минимизации). Он относительно старый (с 2010 года), но все еще активный проект.

Вы можете найти его на github: https://github.com/desandro/imagesloaded

Их официальный сайт: http://imagesloaded.desandro.com/

Почему это лучше, чем использование:

$(window).load() 

Поскольку вы можете загружать изображения динамически, например: jsfiddle

$('#button').click(function(){
    $('#image').attr('src', '...');
});

Ответ 9

Таким образом вы можете выполнить действие, когда загружаются все изображения внутри тела или любого другого контейнера (который зависит от вашего выбора). PURE JQUERY, не требуется никаких pluggins.

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();        
});

Ответ 10

Мое решение похоже на molokoloco. Написано как функция 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);
};

Пример:

<div>
    <img src="img1.png"/>
    <img src="img2.png"/>
</div>
<script>
    $('div').waitForImages(function () {
        console.log('img loaded');
    });
</script>