2014-05-01 21 views
12

Tôi đang sử dụng hệ thống lưới CSS dựa trên tỷ lệ phần trăm. Tôi có một lưới với 4 cột, mỗi 25% tổng chiều rộng của trang. Tôi xuất thẻ hình ảnh của tôi bên trong mỗi "ô 25%" như sau:Tải trọng lười biếng với hình ảnh "phản hồi" (chiều cao không xác định)

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

Khi trình duyệt đổi kích thước, hình ảnh cũng thay đổi kích thước để điền vào 100% của mỗi ô 25%. Trình duyệt chọn một chiều cao, như thể tôi đã đặt "height: auto" (ẩn trong khi bị bỏ qua).

Bây giờ tôi muốn thêm khả năng tải chậm vào điều này. Vấn đề là trước khi hình ảnh được tải, chiều cao của chúng trên trang không xác định. Trình duyệt phải tải xuống hình ảnh & quan sát tỷ lệ khung hình của nó và tính chiều cao cho nó. Trước đó, tất cả các hình ảnh có chiều cao là 1px. Vì mỗi hình ảnh có chiều cao là 1px, tất cả chúng đều được coi là "bên trong khung nhìn" và được tải ngay lập tức.

Hiện nay tôi có một bằng chứng của khái niệm mà trước khi xuất ra các thẻ img, tôi tính toán tỷ lệ hình ảnh khía cạnh trên máy chủ, và đầu ra trong một thuộc tính dữ liệu:

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

Sau đó, khi sự kiện "tài liệu sẵn sàng", tôi lặp qua mỗi hình ảnh và thiết lập một 'chiều cao' giá trị cố định bằng pixel trước khi tải lười biếng:

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

Điều này dường như được làm việc, theo nghĩa là nó không còn tải tất cả hình ảnh tại cùng một thời gian, nhưng chỉ tải hình ảnh khi tôi cuộn.

Tuy nhiên, có vẻ như nó có thể gây ra sự cố mới, chẳng hạn như hình ảnh bị kéo dài khi người dùng thay đổi kích thước trình duyệt. Tôi sẽ phải chuyển đổi 'chiều cao' trở lại 'tự động' khi một cuộc gọi lại kích hoạt cho tải chậm đã hoàn thành. Điều đó sẽ chăm sóc hình ảnh mà người dùng nhìn thấy - nhưng các hình ảnh dưới màn hình đầu tiên sẽ vẫn có giá trị 'chiều cao' không đúng khi trình duyệt được thay đổi kích thước. Mỗi khi trình duyệt được thay đổi kích cỡ, tôi sẽ phải lặp lại tất cả các hình ảnh trước đây dưới màn hình đầu tiên, đo chiều rộng được cập nhật, đọc tỷ lệ khung hình và cập nhật chiều cao mới, sau đó tải xuống để tải xuống bất kỳ thứ gì hiện ở trên gập lại. Nếu tôi không làm điều này, tải có thể được kích hoạt quá sớm hoặc quá muộn do những hình ảnh có giá trị độ cao sai.

Câu hỏi của tôi là, có cách nào khác để tải hình ảnh lười biếng với chiều cao không xác định, không phải là phương pháp chính xác mà tôi đã mô tả ở đây và nhánh này sẽ có gì? Có bất kỳ nhược điểm nào với phương pháp của tôi, ngoài việc là một nỗi đau cho chương trình?

+1

Hình như bạn đã đóng đinh nó. Trình duyệt chỉ có hai cách để biết kích thước của một hình ảnh: để tải xuống hoặc chỉ định kích thước của nó trong HTML. – Blazemonger

+0

Cảm ơn sự bảo đảm. Tôi cũng đã hình dung ra một số cách tiếp cận mà nó lười tải 4 hình ảnh đầu tiên, sau đó khối cho đến khi chúng được hoàn thành, và sau đó đánh giá lại các vị trí mới của các hình ảnh còn lại. Chỉ có vấn đề là việc ngăn chặn sẽ làm cho mọi việc chậm hơn so với việc không tải chậm ngay từ đầu. –

+1

Ok Tôi vừa mới nhận thức được thủ thuật đệm đáy: http://thisisthat.co.uk/notebook/2013-10-07-lazy-loading-responsive-images http://andmag.se/2012/ 10/responsive-images-lazy-load-và-multiserve-images/ –

Trả lời

5

Gần đây tôi đã gặp sự cố tương tự, kết hợp Isotope với Lazy Load trong bố cục đáp ứng. Đồng vị xác định bố trí dựa trên chiều rộng và chiều cao của hình ảnh khi trang được tải, vì vậy ban đầu, các mục đều bị chồng chéo vì Isotope không tính kích thước chính xác.

Để đảm bảo các mục placeholder được tiết kiệm không gian, tôi đã sử dụng các trick padding-bottom bạn đề cập: http://thisisthat.co.uk/notebook/2013-10-07-lazy-loading-responsive-images (Mặc dù nó có thể đã không được rằng bài chính xác.) Dưới đây là đánh dấu của tôi:

<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> 

Đó là có lẽ nhiều hơn tham gia hơn bạn cần (như toàn bộ div. portfoliofolio-văn bản là một lớp phủ trong đó có khá một chút về kiểu dáng xảy ra). Chìa khóa thực sự chỉ là tính toán phần đệm dưới dựa trên chiều rộng và chiều cao của hình ảnh (mà tôi đã làm trong mẫu với PHP) và thiết lập đó là phần đệm phía dưới của mục mà tôi muốn lưu không gian.

+0

Chúng tôi đang sử dụng đồng vị quá trên một số trang! Tôi cháy một khoảng thời gian mỗi 1000ms trong khi các hình ảnh vẫn đang tải mà nói với đồng vị để vẽ lại. Bằng cách này, các hình ảnh tiếp tục xáo trộn xung quanh trong khi chúng đang tải, thay vì tải trong 1 cột lớn và sau đó được bố trí ở cuối. Bạn có làm tương tự không, và bạn có thể giải thích về cách mà JS "kết dính" tất cả cùng nhau làm việc cho dự án của bạn không? –

2

Đây là giải pháp thanh lịch hơn, từ nhận xét. Nó vẫn đòi hỏi phải viết phía máy chủ tỉ lệ, nhưng với một wrapper div:

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

Sau đó, với JS tôi cung cấp cho các wrapper div một padding-bottom:

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

này cung cấp cho các div kích thước chính xác rằng img cuối cùng sẽ tiêu thụ. sau đó tôi sử dụng sau đây LESS để tải hình ảnh trong khu vực các padding tiêu thụ:

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

Ngay cả bụi:

  1. Set chiều cao và chiều rộng của hình ảnh với một số tùy tiện lớn (như 2000px x 1000px)
  2. Áp dụng CSS sau đây để mỗi người trong số những hình ảnh mong muốn (có lẽ qua một lớp học được chia sẻ):
    max-width: 100%height: auto
  3. Nụ cười wi de :)

Tín dụng cho phương pháp này đi vào Github dryabove người sử dụng, được đưa ra trong this Github issue

+0

Hoạt động tuyệt vời cho tôi! –

+0

Nếu bạn muốn có hình ảnh trình giữ chỗ, ví dụ: nền màu xám với spinner (hoặc bạn muốn thiết kế của bạn giữ cấu trúc đúng với không có gì nhìn thấy được), và hình ảnh chưa được tải, 'height: auto' sẽ không hoạt động. Không có thông tin hình ảnh để tính tỷ lệ đúng chiều cao cho chiều rộng ... –

+0

không may mắn cho tôi trên Chrome 57. Hình ảnh không thể đoán trước chồng chéo theo chiều dọc. – evanmcd

Các vấn đề liên quan