Форматирование html после fetch запроса

Рейтинг: 0Ответов: 1Опубликовано: 28.04.2023

Использую fetch запрос для обновления информации в блоке страницы (загружаются карточки предложений после фильтрации).

Некоторые нюансы:

  1. Карточки расположены внутри контейнера div#cards
  2. Карточки выстраиваются в masonry layout с помощью JS-библиотеки
  3. fetch передает готовую вёрстку всего содержимого для div#cards
  4. fetch вызывается изменением любого фильтра и отдаёт новую вёрстку (обработка происходит на сервере в PHP)
  5. Контент заменяется в div#cards с помощью inner.html

Все работает хорошо, кроме одного нюанса. Скрипт, выстраивающий сетку, не дожидается обновления всего контента в div и запускается раньше, из-за чего нарушается порядок блоков и отображение.

Проверено: установка timeout для скрипта решает проблему, но существует задержка, в ходе которой посетитель видет «сырой» контент без masonry.

Что пробовал делать:

  1. Вызывал скрипт в fetch через then, сразу после передачи inner.html
  2. Вызывал скрипт отдельно, после исполнения fetch
  3. Пытался использовать отслеживание события мутации div, прослушивание не исправило ситуацию
  4. Ставил timeout - помогает, но из-за задержки вёрстка выглядит пару секунд ужасно

Вопрос: возможно ли как-то запустить сборку макета (скрипт) ровно в тот момент, когда контент будет заменен на 100%?

Возможно, есть идеи, куда копать или как по-другому решить вопрос? Благодарю.

Ответы

▲ 0

Проблема, с которой вы сталкиваетесь, связана с асинхронной природой выполнения операций в браузере. Когда вы обновляете содержимое div#cards

с помощью innerHTML, новый контент ещё не полностью отрисован, и скрипт, отвечающий за выстраивание сетки (например, Masonry), начинает работу раньше, чем блоки фактически отображены.

Одним из способов решения этой проблемы является использование события load на изображениях, которые содержатся в карточках предложений. Когда все изображения полностью загружены, вы можете вызвать скрипт, отвечающий за выстраивание сетки.

Чисто в теории этот код может помочь вам оптимизировать своё решение. Дайте мне знать если это поможет

function loadMasonryLayout() {
  // Код для выстраивания сетки (например, вызов Masonry)
  // ...
}

function updateContent(html) {
  var cardsContainer = document.getElementById("cards");
  cardsContainer.innerHTML = html;

  var images = cardsContainer.getElementsByTagName("img");
  var imagesLoaded = 0;

  function imageLoadHandler() {
    imagesLoaded++;
    if (imagesLoaded === images.length) {
      loadMasonryLayout();
    }
  }

  for (var i = 0; i < images.length; i++) {
    images[i].addEventListener("load", imageLoadHandler);
  }
}

function fetchContent() {
  fetch(url)
    .then(function(response) {
      return response.text();
    })
    .then(function(data) {
      updateContent(data);
    })
    .catch(function(error) {
      console.error("Error:", error);
    });
}

// Вызываем функцию fetchContent при изменении фильтра
// или в любом другом месте, где нужно обновить контент
fetchContent();