与jquery同步发送图像请求

时间:2013-04-01 11:27:59

标签: jquery synchronous deferred image-load

我有一个页面,我从youtube获取Feed,然后在此页面上显示。每个4行图像共有3行,每个图像对应于YouTube视频。我从youtube Feed本身获得了这些图片链接。

我想要实现的是在渲染这些图像时,我想一次从youtube获取一行图像。如果图像加载没有完成,我想等到下一行图像被提取。

有人可以指导我如何做到这一点吗?我读了关于jquery延迟对象和回调的东西,但是因为jquery / js不强,所以不能真正破解这个。 js异步执行,因此所有图像请求都是一个接一个地进行,并且无法使js等待,直到每行的图像在下一行被发送之前完全呈现。

我目前有一个for循环和diaply图像如下:

$j("#thumbnail_image_"+i).css({'background-image':'url('+cdnPath+')'});
myImage[i].src = cdnPath;

2 个答案:

答案 0 :(得分:0)

基本上,如果使用正确的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设置背景,我认为无法实现。

Demo

答案 1 :(得分:0)

如果您想使用Deferreds / Promises执行此操作,则可以执行以下操作:

$(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()链是控制行加载序列的机制。

代码比其他答案中的代码更笨重,但它对你来说稍微多一点,因为它包含一个超时机制。如果您有更简洁的方法在每行中选择图像,它将简化。