与jquery同步发送图像请求
问题描述:
我有一个页面,我从YouTube获取提要,然后在此页面上显示。每行有4行,每行对应3个YouTube视频。我从youtube feed本身获得这些图片链接。与jquery同步发送图像请求
我想要实现的是在渲染这些图像时,我想一次从一行中的YouTube上获取图像。如果图像加载没有完成,我想等到下一行图像被提取。
有人能指导我如何做到这一点吗?我读了关于jQuery延期对象和回调的东西,但是因为我没有强大的jquery/js无法真正破解这一个。 js异步执行,因此所有图像请求都会一个接一个地执行,并且无法让js等待,直到每行的图像在下一行发送前完全呈现。
我有一个对当前循环和diaply图片如下:
$j("#thumbnail_image_"+i).css({'background-image':'url('+cdnPath+')'});
myImage[i].src = cdnPath;
答
基本上,如果你使用正确的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元素。不要忘记在每一行中将count设置为0。因此你不需要JQuery。
如果你不使用IMG元素并为div设置背景,我认为它不可能实现。
答
如果你想这样做,与Deferreds /许诺,那么,你可以这样做如下:
$(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()
负载一行,并返回一个该行在加载或超时时已解决的Promise。
的代码的其余部分:
- 建立用于图像的装置,以由行索引来选择。
- 建立了一个种子Deferred,它立即解析以允许加载过程开始。
- 建立了几个其他的变量。
- 循环遍历行建立一个
.then()
链,它随着它的进展调用loadRow()
。
.then()
链是控制行加载顺序的机制。
该代码比其他答案中的代码体积更大,但它对于您来说也稍微多一点,因为它包含超时机制。如果您有更简洁的方法选择每一行中的图像,它将会简化。
为什么你同时设置img.src和background-image? – Tommi