Javascript - выполнить после загрузки всех изображений
Прочитав другие вопросы, я подумал
window.onload=...
ответит на мой вопрос. Я пробовал это, но он выполняет код в момент загрузки страницы (не после загрузки изображений).
Если какая-либо разница, изображения поступают из CDN и не являются относительными.
Кто-нибудь знает решение? (Я не использую jQuery)
Ответы
Ответ 1
Вот быстрый взлом для современных браузеров:
var imgs = document.images,
len = imgs.length,
counter = 0;
[].forEach.call( imgs, function( img ) {
img.addEventListener( 'load', incrementCounter, false );
} );
function incrementCounter() {
counter++;
if ( counter === len ) {
console.log( 'All images loaded!' );
}
}
Как только все изображения будут загружены, ваша консоль покажет "Все изображения загружены!".
Что делает этот код:
- Загрузите все изображения в переменную из документа
- Прокрутка этих изображений
- Добавить прослушиватель для события "load" на каждом из этих изображений для запуска функции
incrementCounter
-
incrementCounter
увеличит счетчик
- Если счетчик достиг длины изображений, это означает, что все они загружены.
Наличие этого кода в кросс-браузере не будет таким сложным, это просто чище, как это.
Ответ 2
Promise Pattern решит эту проблему наилучшим образом, я предоставил if.js библиотеку с открытым исходным кодом для решения проблемы загрузки всех изображений.
function loadImage (src) {
var deferred = when.defer(),
img = document.createElement('img');
img.onload = function () {
deferred.resolve(img);
};
img.onerror = function () {
deferred.reject(new Error('Image not found: ' + src));
};
img.src = src;
// Return only the promise, so that the caller cannot
// resolve, reject, or otherwise muck with the original deferred.
return deferred.promise;
}
function loadImages(srcs) {
// srcs = array of image src urls
// Array to hold deferred for each image being loaded
var deferreds = [];
// Call loadImage for each src, and push the returned deferred
// onto the deferreds array
for(var i = 0, len = srcs.length; i < len; i++) {
deferreds.push(loadImage(srcs[i]));
// NOTE: We could push only the promise, but since this array never
// leaves the loadImages function, it ok to push the whole
// deferred. No one can gain access to them.
// However, if this array were exposed (e.g. via return value),
// it would be better to push only the promise.
}
// Return a new promise that will resolve only when all the
// promises in deferreds have resolved.
// NOTE: when.all returns only a promise, not a deferred, so
// this is safe to expose to the caller.
return when.all(deferreds);
}
loadImages(imageSrcArray).then(
function gotEm(imageArray) {
doFancyStuffWithImages(imageArray);
return imageArray.length;
},
function doh(err) {
handleError(err);
}
).then(
function shout (count) {
// This will happen after gotEm() and count is the value
// returned by gotEm()
alert('see my new ' + count + ' images?');
}
);
Ответ 3
Использование window.onload
не будет работать, потому что оно срабатывает после загрузки страницы, однако изображения не включены в это определение загруженного.
Общим решением является ImagesLoaded плагин jQuery.
Если вы не любите использовать jQuery вообще, вы можете хотя бы попробовать преобразовать этот плагин в чистый Javascript. В 93 важных строках кода и хорошем комментировании это не должно быть трудной задачей.
Ответ 4
У вас может быть событие onload на изображении, которое может вызвать функцию, выполняющую обработку... Что касается обработки, если загружаются все изображения, я не уверен, будет ли работать какой-либо из следующих механизмов:
имеет функцию, которая подсчитывает количество изображений, для которых вызывается onload, если это равно общему числу изображений на вашей странице, то выполните необходимую обработку.
Ответ 5
<title>Pre Loading...</title>
</head>
<style type="text/css" media="screen"> html, body{ margin:0;
padding:0; overflow:auto; }
#loading{ position:fixed; width:100%; height:100%; position:absolute; z-index:1; ackground:white url(loader.gif) no-repeat center; }**
</style>
<script> function loaded(){
document.getElementById("loading").style.visibility = "hidden"; }
</script>
<body onload="loaded();"> <div id="loading"></div>
<img id="img" src="avatar8.jpg" title="AVATAR" alt="Picture of Avatar
movie" />
</body>
Ответ 6
Немного поздно в игре, но я нашел следующий метод наиболее простым:
function waitForImages () {
let isLoading = true
while (isLoading) {
const loading = [].slice.call(document.images).filter(img => img.complete !== true)
if (!loading.length > 0) {
isLoading = true
return
}
}
}
Обратите внимание, что это блокирующий код (полезно, если вы пытаетесь обеспечить загрузку изображений в нечто вроде phantomjs)
Ответ 7
Я собирался предложить то же самое, что сказал Базнья.
Кроме того, еще один возможный вариант, который, возможно, не такой надежный, но простой в обслуживании, - это выбрать самое важное/самое большое изображение и прикрепить событие onload только к одному.
Преимущество здесь в том, что вместо изменения кода, если вы позже добавите больше изображений на свою страницу.
Ответ 8
Это прекрасно работает:
$(function() {
$(window).bind("load", function() {
// code here
});
});