3 быстрых исправления для обеспечения правильной загрузки образа Bootstrap Masonry при посещении первой страницы

May 03 2023
Создавая свой личный веб-сайт с использованием JavaScript и Bootstrap, я столкнулся с проблемой отображения карточек контента в разделе моего проекта. Используя простой класс «строка» из системы сетки Bootstrap, я создал блоки столбцов, где каждый столбец имел ту же высоту, что и самая высокая карта на той же горизонтальной оси.
Bootstrap 5 и библиотека Masonry JavaScript

Создавая свой личный веб-сайт с использованием JavaScript и Bootstrap, я столкнулся с проблемой отображения карточек контента в разделе моего проекта. Используя простой класс « строка » из системы сетки Bootstrap , я создал блоки столбцов, где каждый столбец имел ту же высоту, что и самая высокая карта на той же горизонтальной оси.

Это не было бы проблемой, если бы все мои карты имели одинаковые размеры, но длина содержимого моей карты может быть разной. Мое решение состояло в том, чтобы использовать библиотеку Masonry для компоновки каскадной сетки, как это рекомендовано в документации Bootstrap . Это сработало отлично, за исключением одной небольшой проблемы. Первая проблема с загрузкой страницы, связанная с изображениями и Masonry.

<div class="row grid" data-masonry='{"percentPosition": true }'>

Решение?

Я потратил смущающее количество времени, пытаясь определить и решить проблему, с которой столкнулся, и я был не одинок. Есть много других сообщений, разбросанных по форумам, с просьбой найти правильные решения. Попробовав почти все из них, я решил объединить все свои знания в этой статье, чтобы избавить будущих пользователей Masonry от необходимости отслеживать их все.

Решение 1. Promise.all()

Это было решение , рекомендованное самой командой Masonry , и именно его я использовал для устранения первой проблемы с загрузкой моего личного веб-сайта. Добавьте тег script в конец вашего html-файла, который использует Promise.all() для ожидания завершения рендеринга всех изображений в вашем html-элементе и только затем применяет Masonry. Подобные решения также могут быть достигнуты без использования промисов, как показано в первой половине этой статьи . Это хорошее решение, если у вас, как у меня, не так много ресурсов изображений, которые нужно ожидать, но это может стать проблемой, если у вас много изображений.

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();
});

Если у вас много ресурсов изображений, возможно, стоит использовать библиотеку imagesLoaded , которая представляет собой библиотеку JavaScript, созданную той же командой, которая создала Masonry. Просто импортируйте сценарий CDN или установите его с помощью менеджера пакетов, и все готово. В документации также есть отличные примеры использования imagesLoaded в ванильном JavaScript и jQuery. Сообщение о переполнении стека от 2021 года отлично объяснило, как исправить ошибку Masonry с помощью imagesLoaded, и в настоящее время его может использовать человек, создавший сообщение на своем личном веб-сайте , когда вы нажмете «Проверить».

$('#portfolio-section').imagesLoaded( function() {
  $('.grid').masonry({
    itemSelector: '.portfolio-item',
    percentPosition: true
  })
});

Третье решение, предложенное сообществом, состоит в том, чтобы изменить тег скрипта, который Bootstrap рекомендует в своей документации в конце, с асинхронного на синхронный. Идея здесь в том, что если библиотека Masonry перестанет работать асинхронно с остальной частью html, то графические активы успеют загрузиться первыми. Мне не удалось воспроизвести это решение, но оно было выдвинуто и одобрено другим пользователем Bootstrap в вопросе, открытом на GitHub Masonry здесь .

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