Isotope — мощная библиотека для динамической сортировки, фильтрации и расположения элементов на веб-странице. При интеграции с современными фреймворками, такими как React, Vue или Angular, важно учитывать особенности работы виртуального DOM и реактивного обновления данных, чтобы обеспечить корректное функционирование анимаций и перестроение сетки.
Инициализация и работа с компонентами
В React элементы создаются через JSX, а DOM управляется виртуальным
представлением. Для корректной работы Isotope требуется инициализировать
его после того, как компоненты отрендерены в DOM. Обычно это делается в
методе useEffect для функциональных компонентов или в
componentDidMount для классовых.
import { useEffect, useRef } from 'react';
import Isotope from 'isotope-layout';
function Gallery({ items }) {
const gridRef = useRef(null);
const iso = useRef(null);
useEffect(() => {
iso.current = new Isotope(gridRef.current, {
itemSelector: '.grid-item',
layoutMode: 'masonry'
});
return () => iso.current.destroy();
}, []);
useEffect(() => {
iso.current.reloadItems();
iso.current.arrange();
}, [items]);
return (
{items.map(item => (
{item.content}
))}
);
}
Особенности:
useRef позволяет сохранить экземпляр
Isotope между рендерами без пересоздания.items) необходимо вызвать
reloadItems и arrange для перерасчёта
расположения элементов.useEffect, так как это нарушает жизненный цикл React.Подход через директивы и lifecycle hooks
Во Vue инициализация Isotope чаще всего выполняется в хукe
mounted, когда DOM полностью доступен. При реактивных
изменениях массива элементов следует использовать nextTick
для ожидания обновления DOM перед перестройкой сетки.
{{ item.content }}
Особенности:
nextTick гарантирует, что DOM обновлен перед пересчётом
сетки.watch позволяет автоматически реагировать
на изменения в массиве элементов.Директивы и сервисы
В Angular Isotope обычно интегрируется через директиву, чтобы
управлять элементами в DOM после их рендера. Инициализация выполняется в
хукe ngAfterViewInit, а обновление при изменении данных
через ngOnChanges или ChangeDetectorRef.
import { Directive, ElementRef, Input, OnChanges, AfterViewInit, SimpleChanges } from '@angular/core';
import Isotope from 'isotope-layout';
@Directive({
selector: '[appIsotope]'
})
export class IsotopeDirective implements AfterViewInit, OnChanges {
@Input() items: any[] = [];
private iso: any;
constructor(private el: ElementRef) {}
ngAfterViewInit() {
this.iso = new Isotope(this.el.nativeElement, {
itemSelector: '.grid-item',
layoutMode: 'masonry'
});
}
ngOnChanges(changes: SimpleChanges) {
if (changes['items'] && this.iso) {
this.iso.reloadItems();
this.iso.arrange();
}
}
}
Особенности:
ngAfterViewInit гарантирует наличие элементов DOM перед
инициализацией.ngOnChanges обеспечивает реакцию на изменения входных
данных.imagesLoaded,
чтобы избежать неправильного расчёта размеров при загрузке
картинок.reloadItems и arrange.arrange, filter,
sort) вызываются на экземпляре Isotope, поэтому важно
хранить его в отдельной переменной, привязанной к жизненному циклу
компонента.При загрузке данных с сервера порядок действий должен быть следующим:
reloadItems.arrange для корректного расположения
элементов.Для изображений используется плагин imagesLoaded:
imagesLoaded(gridRef.current, () => {
iso.current.reloadItems();
iso.current.arrange();
});
Это предотвращает визуальные сдвиги и «прыжки» элементов при загрузке картинок.
Isotope предоставляет гибкие методы для управления отображением элементов:
filter(selector) — фильтрует элементы по
CSS-селектору.arrange({ sortBy: 'name' }) — сортирует элементы по
заданному критерию.iso.arrange({
filter: '.active',
sortBy: 'date'
});
Для реактивных фреймворков такие вызовы необходимо производить после каждого обновления DOM, чтобы сохранить синхронизацию состояния.