Как реализовать бесконечную прокрутку в веб-приложении

3
компьютеры и технологии 19.webp.webp

Последнее обновление 15.11.2023 — Василий Иванов

Бесконечная прокрутка позволяет контенту загружаться непрерывно по мере того, как пользователи перемещаются вниз по странице, в отличие от традиционного метода разбивки по страницам с загрузкой по клику. Эта функция может обеспечить более плавную работу, особенно на мобильных устройствах.

Узнайте, как настроить бесконечную прокрутку с помощью простого HTML, CSS и JavaScript.

Настройка внешнего интерфейса

Начните с базовой структуры HTML для отображения вашего контента. Вот пример:

        <!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="style.css" />
</head>
<body>
    <h1>Infinite Scroll Page</h1>

    <div class="products__list">
      <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg"
           alt="Jacket" />

      <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg"
           alt="Jacket" />

      <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg"
           alt="Jacket" />

      <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg"
           alt="Jacket" />

      <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg"
           alt="Jacket" />

      <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg"
           alt="Jacket" />
    </div>

    <script src="script.js"></script>
</body>
</html>

Эта страница содержит серию изображений-заполнителей и ссылается на два ресурса: файл CSS и файл JavaScript.

CSS-стиль для прокручиваемого контента

Чтобы отобразить изображения-заполнители в сетке, добавьте следующий CSS в файл style.css:

        * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html { font-size: 62.5%; }

body {
  font-family: Cambria, Times, "Times New Roman", serif;
}

h1 {
  text-align: center;
  font-size: 5rem;
  padding: 2rem;
}

img {
  width: 100%;
  display: block;
}

.products__list {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  justify-content: center;
}

.products__list > * {
  width: calc(33% - 2rem);
}

.loading-indicator {
  display: none;
  position: absolute;
  bottom: 30px;
  left: 50%;
  background: #333;
  padding: 1rem 2rem;
  color: #fff;
  border-radius: 10px;
  transform: translateX(-50%);
}

На данный момент ваша страница должна выглядеть так:

Основная реализация с помощью JS

Отредактируйте скрипт.js. Чтобы реализовать бесконечную прокрутку, вам необходимо определить, когда пользователь прокрутил нижнюю часть контейнера содержимого или страницы.

        "use strict";

window.addEventListener("scroll", () => {
  if (
    window.scrollY + window.innerHeight >=
      document.documentElement.scrollHeight - 100
  ) {
    // User is near the bottom, fetch more content
    fetchMoreContent();
  }
});

Затем создайте функцию для получения дополнительных данных-заполнителей.

        async function fetchMoreContent() {
  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    let data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("There was a problem fetching new content:", error);
  } finally {
    console.log("Fetch function fired");
  }
}

Для этого проекта вы можете использовать API от fakestoreapi.

Чтобы убедиться, что ваши данные извлекаются при прокрутке, взгляните на консоль:

Вы заметите, что ваши данные извлекаются несколько раз при прокрутке, что может быть фактором, снижающим производительность устройства. Чтобы предотвратить это, создайте начальное состояние выборки данных:

        let isFetching = false;

Затем измените функцию выборки, чтобы она извлекала данные только после завершения предыдущей выборки.

        async function fetchMoreContent() {
  if (isFetching) return; // Exit if already fetching

  isFetching = true; // Set the flag to true

  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    let data = await response.json();
  } catch (error) {
    console.error("There was a problem fetching new content:", error);
  } finally {
    console.log("Fetch function fired");
    isFetching = false; // Reset the flag to false
  }
}

Отображение нового контента

Чтобы отображать новый контент, когда пользователь прокручивает страницу вниз, создайте функцию, которая добавляет изображения в родительский контейнер.

Сначала выберите родительский элемент:

        const productsList = document.querySelector(".products__list");

Затем создайте функцию для добавления содержимого.

        function displayNewContent(data) {
  data.forEach((item) => {
    const imgElement = document.createElement("img");
    imgElement.src = item.image;
    imgElement.alt = item.title;
    productsList.appendChild(imgElement); // Append to productsList container
  });
}

Наконец, измените функцию выборки и передайте полученные данные в функцию добавления.

        async function fetchMoreContent() {
  if (isFetching) return;

  isFetching = true;

  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    let data = await response.json();
    displayNewContent(data);
  } catch (error) {
    console.error("There was a problem fetching new content:", error);
  } finally {
    console.log("Fetch function fired");
    isFetching = false;
  }
}

И теперь ваша бесконечная прокрутка работает.

Улучшения бесконечной прокрутки

Чтобы улучшить взаимодействие с пользователем, вы можете отображать индикатор загрузки при загрузке нового контента. Начните с добавления этого HTML.

        <h1 class="loading-indicator">Loading...</h1>

Затем выберите элемент загрузки.

        const loadingIndicator = document.querySelector(".loading-indicator");

Наконец, создайте две функции для переключения видимости индикатора загрузки.

        function showLoadingIndicator() {
  loadingIndicator.style.display = "block";
  console.log("Loading...");
}

function hideLoadingIndicator() {
  loadingIndicator.style.display = "none";
  console.log("Finished loading.");
}

Затем добавьте их в функцию выборки.

        async function fetchMoreContent() {
  if (isFetching) return; // Exit if already fetching

  isFetching = true;
  showLoadingIndicator(); // Show loader

  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("Network response was not ok");
    }

    let data = await response.json();
    displayNewContent(data);
  } catch (error) {
    console.error("There was a problem fetching new content:", error);
  } finally {
    console.log("Fetch function fired");
    hideLoadingIndicator(); // Hide loader
    isFetching = false;
 }
}

Который дает:

Хорошие практики для бесконечной прокрутки

Вот некоторые рекомендации, которым следует следовать:

  • Не извлекайте слишком много элементов одновременно. Это может привести к перегрузке браузера и снижению производительности.

  • Вместо того, чтобы получать контент сразу после обнаружения события прокрутки, используйте функцию устранения дребезга, чтобы немного задержать выборку. Это может предотвратить чрезмерные сетевые запросы.

  • Не все пользователи предпочитают бесконечную прокрутку. При желании предложите возможность использовать компонент нумерации страниц.

  • Если контента для загрузки больше нет, сообщите об этом пользователю, вместо того чтобы постоянно пытаться получить больше контента.

Освоение плавной загрузки контента

Бесконечная прокрутка позволяет пользователям плавно просматривать контент и отлично подходит для людей, использующих мобильные устройства. Если вы воспользуетесь советами и важными советами из этой статьи, вы сможете добавить эту функцию на свои сайты.

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