3 cách khắc phục nhanh để đảm bảo tải đúng hình ảnh Bootstrap Masonry khi truy cập trang đầu tiên

Trong khi tạo trang web cá nhân của riêng mình bằng JavaScript và Bootstrap, tôi gặp sự cố hiển thị thẻ nội dung trong phần dự án của mình. Sử dụng một lớp “ hàng ” đơn giản từ hệ thống Lưới của Bootstrap , tôi đã tạo các khối cột trong đó mỗi cột có cùng chiều cao với thẻ cao nhất trong cùng một trục ngang.
Đây sẽ không phải là vấn đề nếu tất cả các thẻ của tôi có cùng kích thước, nhưng độ dài của nội dung thẻ của tôi có thể thay đổi. Giải pháp của tôi là sử dụng thư viện Masonry để bố trí lưới theo tầng như được đề xuất trong tài liệu Bootstrap . Nó hoạt động rất tốt, mong đợi một vấn đề nhỏ. Vấn đề tải trang đầu tiên đi kèm với hình ảnh và Masonry.
<div class="row grid" data-masonry='{"percentPosition": true }'>
Giải pháp?
Tôi đã dành một khoảng thời gian đáng xấu hổ để cố gắng xác định và giải quyết vấn đề mà tôi đang gặp phải và tôi không đơn độc. Có rất nhiều bài đăng khác nằm rải rác trên các diễn đàn yêu cầu giải pháp thích hợp. Sau khi thử hầu hết tất cả chúng, tôi quyết định tổng hợp tất cả những gì mình đã học được vào một bài viết này để giúp những người dùng Masonry trong tương lai không gặp khó khăn trong việc theo dõi tất cả chúng.
Giải pháp 1: Promise.all()
Đây là giải pháp do chính nhóm Masonry đề xuất và là giải pháp tôi đã sử dụng để khắc phục sự cố tải đầu tiên cho trang web cá nhân của mình. Thêm một thẻ tập lệnh vào cuối tệp html của bạn sử dụng Promise.all() để chờ tất cả các hình ảnh trong phần tử html của bạn kết thúc hiển thị và chỉ sau đó mới áp dụng Masonry. Các giải pháp tương tự cũng có thể đạt được mà không cần phải sử dụng các lời hứa như đã trình bày trong nửa đầu của bài viết này . Đây là một giải pháp tốt nếu bạn không có nhiều nội dung hình ảnh như tôi, nhưng nó có thể là một vấn đề nếu bạn có nhiều hình ảnh.
Promise.all(Array.from(document.images)
.filter(img => !img.complete)
.map(img => new Promise(resolve => { img.onload = img.onerror = resolve; })))
.then(() => {
var msnry = new Masonry('.grid');
msnry.layout();
});
Nếu bạn có nhiều nội dung hình ảnh thì có thể đáng để sử dụng thư viện imagesLoaded , đây là thư viện JavaScript được tạo bởi cùng một nhóm đã tạo ra Masonry. Chỉ cần nhập tập lệnh CDN của anh ấy hoặc cài đặt nó bằng trình quản lý gói và bạn đã sẵn sàng. Tài liệu này cũng có các ví dụ tuyệt vời về cách sử dụng imageLoaded trong vanilla JavaScript và jQuery. Một bài đăng trên Stack Overflow từ năm 2021 đã giải thích rất tốt cách khắc phục lỗi Masonry bằng cách sử dụng imagesLoaded và hiện tại người tạo bài đăng trên trang web cá nhân của họ có thể thấy nó đang được sử dụng khi bạn nhấn kiểm tra.
$('#portfolio-section').imagesLoaded( function() {
$('.grid').masonry({
itemSelector: '.portfolio-item',
percentPosition: true
})
});
Giải pháp thứ ba đã được cộng đồng đưa ra là thay đổi thẻ tập lệnh mà Bootstrap đề xuất trong tài liệu của nó ở cuối từ không đồng bộ thành đồng bộ hóa. Ý tưởng ở đây là nếu thư viện Masonry ngừng chạy không đồng bộ với phần còn lại của html, thì nội dung hình ảnh sẽ có thời gian tải trước. Tôi không thể sao chép giải pháp này, nhưng nó đã được một người dùng Bootstrap khác đưa ra và xác nhận trong một sự cố được mở trên Masonry GitHub tại đây .
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/masonry.pkgd.min.js" integrity="sha384-GNFwBvfVxBkLMJpYMOABq3c+d3KnQxudP/mGPkzpZSTYykLBNsZEnG2D9G/X/+7D" crossorigin="anonymous" sync></script>