Отправка запросов на изображения синхронно с jquery
У меня есть страница, где я получаю канал с YouTube, а затем отображать это на этой странице. Есть 3 строки каждого из 4 изображений, каждое из которых соответствует видео на YouTube. Я получаю эти ссылки на изображения с самого канала YouTube.
Чего я хочу достичь, так это рендеринга этих изображений, я хочу получить изображение с YouTube по одной строке за раз. Если загрузка изображений не завершена, я хотел бы подождать, пока будут получены изображения следующей строки.
Кто-нибудь может подсказать мне, как это можно сделать? Я читаю материал о отложенных объектах jquery и обратных вызовах, но так как я не силен в jquery/js, я не могу его взломать. Js выполняется асинхронно, и поэтому все запросы изображений выполняются один за другим, и я не могу заставить j ждать, пока изображения для каждой строки не будут полностью обработаны перед отправкой следующей строки.
В настоящее время у меня есть цикл for и изображения в следующем формате:
$j("#thumbnail_image_"+i).css({'background-image':'url('+cdnPath+')'});
myImage[i].src = cdnPath;
2 ответа
Если вы хотите сделать это с отсрочкой / обещанием, то вы можете сделать это следующим образом:
$(function() {
function loadRow($imgs, timeout) {
var dfrd = $.Deferred(),
n = 0;
$imgs.each(function() {
this.onload = function() {
if(++n == $imgs.length) { dfrd.resolve(); }
}
this.src = "/path/to/img";
});
setTimeout(dfrd.resolve, timeout);//in case of slow network or img.onload failure
return dfrd.promise();
}
var $images = $(img.whatever),//adjust as required
rowlength = 5,//adjust as required
rowFilter = function(i) {
return function(index) {
return (index > i * rowlength) && (index < (i+1) * rowlength);
}
},
nRows = Math.ceil($images.length / rowlength);
timeout = 10000,//(ms) adjust as required
d = $.Deferred().resolve();
for(var i=0; i<nRows; i++) {
var $imgs = $images.filter(rowFilter(i));
d = d.then(loadRow($imgs, timeout));
}
});
непроверенной
loadRow()
загружает строку и возвращает Обещание, которое разрешается при загрузке строки или времени ожидания.
Остальная часть кода:
- устанавливает средства для изображений, которые будут выбраны по индексу строки.
- устанавливает отсроченное начальное число, которое разрешается немедленно, чтобы начать процесс загрузки.
- устанавливает пару других варов.
- петли по строкам
.then()
цепь, которая вызываетloadRow()
как это прогрессирует.
.then()
Цепочка - это механизм, который контролирует последовательность загрузки строк.
Код громоздче, чем в другом ответе, но он также делает для вас немного больше, поскольку включает механизм тайм-аута. Это упростит, если у вас есть более сжатые средства выбора изображений в каждой строке.
По сути, если вы используете надлежащий элемент IMG для хранения изображения, вы можете подписаться на его события onload и onerror. Тогда вы можете посчитать, сколько изображений уже загружено
var loaded = 0;
for (var i = 0; i < imgtags.length; i++) {
imgtags[i].src = "/path/to/img";
function handle() {
loaded++;
if (loaded == imgtags.length) {
loaded = 0;
// call next row or finish
};
};
img.onload = handle;
img.onerror = function () {
handle();
// possible error handling here
};
};
где imgtags - массив с элементами IMG в текущей строке. Не забудьте установить счетчик на 0 в каждой строке. Поэтому вам не нужен JQuery для этого.
Если вы не используете элемент IMG и не устанавливаете фон для div, я не думаю, что это возможно.