2013-04-01 97 views
0

我有一個頁面,我從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; 
+0

爲什麼你同時設置img.src和background-image? – Tommi

回答

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元素。不要忘記在每一行中將count設置爲0。因此你不需要JQuery。

如果你不使用IMG元素併爲div設置背景,我認爲它不可能實現。

Demo

+0

這不起作用。即使圖像未完全加載,JS執行也不會停止,因爲它是異步的。對於上面的代碼,如果我的網絡速度很慢,並且需要10秒才能完全下載圖像,則第二行將不會顯示。 –

+0

很難重現「慢速網絡」,但我沒有看到爲什麼10秒加載會影響此代碼的原因。你可以解釋嗎? – Tommi

+0

我已經添加了小提琴,對於常規網絡它的工作原理,當然你應該用遞歸加載代替最後的嵌套調用。 – Tommi

0

如果你想這樣做,與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()鏈是控制行加載順序的機制。

該代碼比其他答案中的代碼體積更大,但它對於您來說也稍微多一點,因爲它包含超時機制。如果您有更簡潔的方法選擇每一行中的圖像,它將會簡化。