Официальный способ попросить jQuery дождаться загрузки всех изображений перед выполнением чего-либо
В jQuery, когда вы делаете это:
$(function() {
alert("DOM is loaded, but images not necessarily all loaded");
});
Он ожидает загрузки DOM и выполняет ваш код. Если все изображения не загружены, он все равно выполняет код. Это, очевидно, то, что мы хотим, если мы инициализируем какие-либо вещи DOM, такие как показ или скрытие элементов или присоединение событий.
Допустим, что мне нужна анимация, и я не хочу, чтобы она работала до тех пор, пока не будут загружены все изображения. Есть ли официальный способ сделать это в jQuery?
Лучший способ у меня есть, чтобы использовать <body onload="finished()">
, но я не хочу этого делать, если не буду этого делать.
Примечание: в jQuery 1.3.1 есть ошибка в Internet Explorer, которая на самом деле ожидает загрузки всех изображений перед выполнением кода внутри $function() { }
, Так что, если вы используете эту платформу, вы получите поведение, которое я ищу, а не правильное поведение, описанное выше.
11 ответов
С помощью 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.
});
Я написал плагин, который может запускать обратные вызовы, когда изображения загружаются в элементы, или запускаться один раз для каждого загруженного изображения.
Это похоже на $(window).load(function() { .. })
, за исключением того, что позволяет определить любой селектор для проверки. Если вы хотите знать, когда все изображения в #content
(например) загрузили, это плагин для вас.
Он также поддерживает загрузку изображений, на которые есть ссылки в CSS, например: background-image
, list-style-image
, так далее.
waitForImages плагин jQuery
Пример использования
$('selector').waitForImages(function() {
alert('All images are loaded.');
});
Больше документации доступно на странице GitHub.
$(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);
Для тех, кто хочет получать уведомления о завершении загрузки одного изображения, которое запрашивается после $(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");
});
Ни один из ответов до сих пор не дал то, что кажется самым простым решением.
$('#image_id').load(
function () {
//code here
});
Я бы порекомендовал использовать imagesLoaded.js
библиотека JavaScript
Почему бы не использовать JQuery's $(window).load()
?
Как указано на https://stackru.com/questions/26927575/why-use-imagesloaded-javascript-library-versus-jquerys-window-load/26929951
Это вопрос сферы. imagesLoaded позволяет нацеливать набор изображений, тогда как
$(window).load()
предназначается для всех ресурсов - включая все изображения, объекты, файлы.js и.css и даже iframes. Скорее всего, imagesLoaded будет срабатывать раньше, чем$(window).load()
потому что он нацелен на меньший набор активов.
Другие веские причины использовать загруженные изображения
- официально поддерживается IE8+
- лицензия: лицензия MIT
- зависимости: нет
- вес (минимизированный и сжатый): 7 КБ минимизированный (легкий!)
- скачать конструктор (помогает снизить вес): не нужно, уже крошечный
- на Github: ДА
- сообщество и участники: довольно большое, более 4000 участников, хотя всего 13 участников
- история и вклады: стабильный как относительно старый (с 2010 года), но все еще активный проект
Ресурсы
- Проект на github: https://github.com/desandro/imagesloaded
- Официальный сайт: http://imagesloaded.desandro.com/
- Проверьте, загружено ли изображение (без ошибок) в JavaScript
- https://stackru.com/questions/26927575/why-use-imagesloaded-javascript-library-versus-jquerys-window-load
- библиотека загруженного изображения: какая поддержка браузера и устройства?
С 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);
});
});
Таким образом, вы можете выполнить действие, когда все изображения внутри тела или любого другого контейнера (в зависимости от вашего выбора) загружены. PURE JQUERY, никаких плагинов не требуется.
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();
});
Мое решение похоже на 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>
Используйте imagesLoaded PACKAGED v3.1.8 (6,8 Кбайт при минимизации). Это относительно старый (с 2010 года), но все еще активный проект.
Вы можете найти его на github: https://github.com/desandro/imagesloaded
Их официальный сайт: http://imagesloaded.desandro.com/
Почему это лучше, чем использовать:
$(window).load()
Потому что вы можете загружать изображения динамически, например: jsfiddle
$('#button').click(function(){
$('#image').attr('src', '...');
});
Я нашел это решение: @Luca Matteis Здесь: https://www.examplefiles.net/cs/508021
Но я немного отредактировал его, как показано на рисунке:
function showImage(el){
$(el).removeClass('hidden');
$(el).addClass('show');
$(el).prev().removeClass('show');
$(el).prev().addClass('hidden');
}
<img src="temp_image.png" />
<img class="hidden" src="blah.png" onload="showImage(this);"/>