Блог с поиском и тегами

Isotope — это мощная библиотека JavaScript для динамической фильтрации, сортировки и анимации элементов на веб-странице. В контексте блога с поиском и тегами она используется для организации постов, чтобы посетитель мог быстро находить записи по категориям или ключевым словам.

Основной принцип работы Isotope заключается в том, что элементы контейнера (например, карточки постов) автоматически перестраиваются и анимируются при изменении фильтров или порядка сортировки. Это достигается с помощью CSS-позиций и JavaScript-логики, без необходимости перезагружать страницу.

Подключение и инициализация

Для работы Isotope необходимо подключить библиотеку через CDN или локальные файлы:

<link rel="stylesheet" href="styles.css">
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>

Создаём HTML-структуру контейнера блога:

<div id="blog-container">
  <div class="blog-item" data-category="tech" data-tags="javascript,web">Пост 1</div>
  <div class="blog-item" data-category="lifestyle" data-tags="health,travel">Пост 2</div>
  <div class="blog-item" data-category="tech" data-tags="css,html">Пост 3</div>
</div>

Инициализация Isotope в Jav * aScript:

const iso = new Isotope('#blog-container', {
  itemSelector: '.blog-item',
  layoutMode: 'fitRows', // другой вариант: 'masonry'
});

Здесь itemSelector указывает, какие элементы нужно обрабатывать, а layoutMode задаёт алгоритм расположения карточек (fitRows выстраивает в сетку по рядам, masonry — в кирпичном стиле).

Фильтрация по категориям

Для фильтрации используется метод arrange, где в опции filter передаётся CSS-селектор элементов, которые должны оставаться видимыми:

function filterByCategory(category) {
  iso.arrange({ filter: `[data-category="${category}"]` });
}

Можно создавать кнопки с категориями:

<button data-filter="tech">Технологии</button>
<button data-filter="lifestyle">Образ жизни</button>

И привязать обработчик:

document.querySelectorAll('button[data-filter]').forEach(button => {
  button.addEventListener('click', () => {
    filterByCategory(button.getAttribute('data-filter'));
  });
});

Фильтрация по тегам

Если требуется более гибкая фильтрация по тегам, можно использовать функцию вместо CSS-селектора:

function filterByTag(tag) {
  iso.arrange({
    filter: function(itemElem) {
      const tags = itemElem.getAttribute('data-tags').split(',');
      return tags.includes(tag);
    }
  });
}

Для кнопок тегов используется аналогичная структура:

<button data-tag="javascript">JavaScript</button>
<button data-tag="web">Web</button>

И обработчик:

document.querySelectorAll('button[data-tag]').forEach(button => {
  button.addEventListener('click', () => {
    filterByTag(button.getAttribute('data-tag'));
  });
});

Поиск по тексту

Isotope поддерживает фильтрацию через текстовый поиск. Для этого создаём input и фильтруем элементы по содержимому:

<input type="text" id="search-input" placeholder="Поиск по блогу...">

Обработчик ввода:

const searchInput = document.getElementById('search-input');

searchInput.addEventListener('input', () => {
  const query = searchInput.value.toLowerCase();
  iso.arrange({
    filter: function(itemElem) {
      return itemElem.textContent.toLowerCase().includes(query);
    }
  });
});

Такой подход позволяет комбинировать поиск с фильтрацией по категориям и тегам.

Комбинированная фильтрация

Для реализации нескольких фильтров одновременно создаётся объект состояния фильтров:

const filters = {
  category: '*',
  tag: '*'
};

function applyFilters() {
  iso.arrange({
    filter: function(itemElem) {
      const category = itemElem.getAttribute('data-category');
      const tags = itemElem.getAttribute('data-tags').split(',');

      const categoryMatch = filters.category === '*' || category === filters.category;
      const tagMatch = filters.tag === '*' || tags.includes(filters.tag);

      return categoryMatch && tagMatch;
    }
  });
}

Обновление фильтров:

document.querySelectorAll('button[data-filter]').forEach(button => {
  button.addEventListener('click', () => {
    filters.category = button.getAttribute('data-filter');
    applyFilters();
  });
});

document.querySelectorAll('button[data-tag]').forEach(button => {
  button.addEventListener('click', () => {
    filters.tag = button.getAttribute('data-tag');
    applyFilters();
  });
});

Сортировка записей

Isotope позволяет сортировать элементы по различным критериям, например, по дате или названию. Для этого задаются data-* атрибуты:

<div class="blog-item" data-date="2026-03-10" data-title="Первый пост">...</div>

Инициализация сортировки:

iso.arrange({
  sortBy: 'date',
  sortAscending: false
});

Можно менять критерий сортировки динамически:

function sortBy(criteria, ascending = true) {
  iso.arrange({
    sortBy: criteria,
    sortAscending: ascending
  });
}

Анимация и кастомизация

Isotope использует CSS-переходы для плавного перемещения элементов. Для настройки скорости анимации и easing:

const iso = new Isotope('#blog-container', {
  itemSelector: '.blog-item',
  layoutMode: 'fitRows',
  transitionDuration: '0.6s', // длительность анимации
  hiddenStyle: { opacity: 0, transform: 'scale(0.8)' },
  visibleStyle: { opacity: 1, transform: 'scale(1)' }
});

Эти параметры позволяют контролировать визуальные эффекты появления и скрытия элементов, создавая более привлекательный интерфейс.

Интеграция с динамическим контентом

Если карточки постов подгружаются асинхронно (например, через AJAX), необходимо уведомить Isotope о новых элементах:

const newItems = document.querySelectorAll('.blog-item.new');
iso.appended(newItems);
iso.layout();

Метод appended добавляет новые элементы в существующий контейнер, а layout пересчитывает их расположение.

Итоговый подход

Использование Isotope для блога с поиском и тегами обеспечивает:

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

Такой подход позволяет создать интерактивный, отзывчивый и визуально привлекательный блог без необходимости перезагрузки страницы.