2014-05-01 61 views
12

我使用的是基於百分比一個CSS網格系統。我有一個4列的網格,每頁的總寬度的25%。我每一個「25%的細胞」像這樣的輸出裏面我的形象標籤:延遲加載與「有求必應」的圖像(未知高度)

<img src="foo.jpg" style="max-width:100%" /> 

當瀏覽器調整大小,圖像也調整填補各25%的細胞的100%。瀏覽器選擇一個高度,就好像我已經放置了「height:auto」(當省略時隱含)。

現在我想延遲加載功能添加到這一點。問題是在加載圖像之前,它們在頁面上的高度是未知的。瀏覽器必須下載圖像&觀察其長寬比,並計算它的高度。在此之前,所有圖像的高度均爲1px。由於每張圖片的高度均爲1px,因此它們都被視爲「在視口內」並立即加載。

目前我有概念證明,其中之前輸出img標籤,我計算在數據屬性與服務器上的圖像的縱橫比,並且輸出:

<img src="foo.jpg" style="max-width:100%" data-aspect="1.7742" /> 

然後,在事件「的文件準備好」,我通過各種圖像循環和之前的延遲加載設置以像素爲單位固定的‘高度’值:

$('img').each(function() { 
     var img = $(this); 
     var width = img.width(); 
     var ratio = img.data('aspectratio'); 
     var height = width/ratio; 
     $(this).css('height', height+'px'); 
    }); 

這似乎是工作,在某種意義上說,它不再裝載在同一圖像時間,但只在我滾動時加載圖像。

然而,現在看來似乎可能會導致新的問題,如爲用戶改變瀏覽器的圖像變得扭曲。當回調觸發延遲加載完成時,我將不得不將「高度」切換回「自動」。這將照顧用戶看到的圖像 - 但是在摺疊後的圖像在瀏覽器被調整大小時仍然具有不正確的「高度」值。每一個瀏覽器大小的時候,我不得不重複了以前的倍以下的所有圖像,測量它們的更新寬度,閱讀他們的寬高比,並更新新的高度,然後再觸發延遲加載,以處理任何事情,現在是上面的折。如果我不這樣做,由於這些圖像的高度值錯誤,可能會導致加載太早或太晚。

我的問題是,有沒有其他的方法來延遲加載圖像與未知的高度,比我在這裏所描述的,並且將這個有什麼後果確切的方法之外?我的方法有什麼缺點,除了編程的痛苦嗎?

+1

給您好像釘它。瀏覽器只有兩種方法可以知道圖像的尺寸:下載它或使用HTML指定它。 – Blazemonger

+0

感謝您的保證。我也在設想一些方法,它懶惰地加載前4張圖像,然後阻止直到完成,然後重新評估剩餘圖像的新位置。唯一的問題是阻塞會讓事情比沒有延遲加載更慢。 –

+1

好的,我剛剛意識到了填充底部的技巧: http://thisisthat.co.uk/notebook/2013-10-07-lazy-loading-responsive-images http://andmag.se/2012/ 10/responsive-images-lazy-load-and-multiserve-images/ –

回答

5

我最近有一個類似的問題,結合IsotopeLazy Load在一個響應式佈局。當頁面加載時,同位素根據圖像的寬度和高度來確定佈局,所以最初的項目都是重疊的,因爲同位素沒有計算出正確的大小。

要確保佔位符項目被節省空間,我用你提到的填充底絕招:http://thisisthat.co.uk/notebook/2013-10-07-lazy-loading-responsive-images(雖然它可能沒有那麼精確的帖子。)這是我的標記:

<article class="portfolio-item"> 
     <a class="portfolio-link" href="img/gallery/thumb90.jpg" style="padding-bottom: 66.2%"> 
      <div class="portfolio-image-wrapper"> 
       <img class="portfolio-image" data-original="img/gallery/thumb90.jpg" width="1000" height="662"> 
      </div> 
      <div class="portfolio-text"> 
       <h1 class="portfolio-item-name"> 
        <span href="#" class="icon" data-icon="e"></span> 
        <span class="portfolio-item-tags">Bridals</span> 
       </h1> 
      </div> 
     </a> 
    </article> 

這可能比你需要更多的參與(因爲整個.portfolio-text div是一個疊加,其中有相當多的樣式正在進行)。真正的關鍵只是在計算基於圖像的寬度和高度(這是我在使用PHP模板一樣)底部填充和設置,當我想節省空間的項目填充底部。

+0

我們實際上在某些頁面上使用同位素!我每隔1000ms就會觸發一次間隔,同時圖像仍在加載,這會告訴同位素重繪。這樣,圖像在裝載時不停地洗牌,而不是裝入一大列,然後安排在最後。你是否也這樣做,你能否詳細說明JS如何「粘合」它們一起適用於你的項目? –

2

下面是來自評論的更優雅的解決方案。它仍然需要編寫的縱橫比服務器端,而是用一個包裝div

<div class="lazy"><img src="foo.jpg" style="max-width:100%" data-aspect="0.75" /></div> 
與JS

然後我給包裝div一個padding-bottom

$('div.lazy').livequery(function() { 
    var c = $(this); 
    var r = c.data('ar'); 
    c.css('padding-bottom', r * 100 + '%'); 
}); 

這給了div的精確尺寸的img最終會消耗。然後我使用下面的少的區域內加載圖像的padding消耗:

div.lazy { 
    max-width:100%; 
    position:relative; 
    img { 
    position:absolute; 
    width:100%; 
    height:100%; 
    } 
} 
5

即使清潔器:

  1. 設置高度和圖像的寬度爲任意-大量(如2000px x 1000px
  2. (或許經由共享類)應用以下CSS到每個期望的圖像的:
    max-width: 100%height: auto
  3. 微笑無線德:)

信用這種方法去Github的用戶dryabove,在this Github issue

+0

適合我! –

+0

如果您想要佔位符圖像,例如帶有微調框的灰色背景(或者你希望你的設計沒有任何可見的東西來保持正確的結構),並且圖像尚未加載,'height:auto'不起作用。有沒有圖像信息來計算正確的高度和寬度的比例... –

+0

在Chrome 57上我沒有運氣。圖像不可預測地垂直重疊。 – evanmcd