Санитизация контента

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

Ключевые понятия:

  • Поппер (Popper) — всплывающий элемент, который необходимо позиционировать.
  • Референс (Reference) — элемент, относительно которого производится позиционирование поппера.
  • Модификаторы (Modifiers) — плагины или функции, которые изменяют поведение позиционирования, например, смещают элемент или предотвращают его выход за границы контейнера.
  • Флоу (Placement) — направление размещения поппера: top, bottom, left, right, с возможностью уточнения варианта через -start или -end.

Инициализация поппера

Для создания поппера используется конструктор Popper или фабричная функция createPopper в более новых версиях:

import { createPopper } from '@popperjs/core';

const reference = document.querySelector('#button');
const popper = document.querySelector('#tooltip');

createPopper(reference, popper, {
  placement: 'top',
  modifiers: [
    {
      name: 'offset',
      options: {
        offset: [0, 8], // смещение по оси X и Y
      },
    },
    {
      name: 'preventOverflow',
      options: {
        boundary: 'viewport', // ограничение внутри окна
      },
    },
  ],
});

Выделение ключевых моментов:

  • placement задает первоначальное направление отображения поппера.
  • Модификатор offset позволяет сдвигать поппер от целевого элемента.
  • Модификатор preventOverflow защищает элемент от выхода за пределы контейнера или окна.

Работа с модификаторами

Модификаторы позволяют гибко управлять поведением поппера. Их можно комбинировать, добавлять свои и изменять стандартные.

Основные встроенные модификаторы:

  • offset — задает смещение элемента от референса.
  • flip — автоматически изменяет позицию поппера, если выбранное направление выходит за границы видимой области.
  • preventOverflow — ограничивает поппер рамками контейнера или окна.
  • arrow — управляет позиционированием стрелки тултипа.
  • computeStyles — отвечает за применение CSS-трансформаций и позиционирование через top и left.

Пример кастомного модификатора:

const customModifier = {
  name: 'customShift',
  enabled: true,
  phase: 'main',
  fn({ state }) {
    state.styles.popper.top = `${parseInt(state.styles.popper.top, 10) + 10}px`;
  },
};

createPopper(reference, popper, {
  modifiers: [customModifier],
});

Модификаторы можно управлять через enabled, изменять порядок их применения и фазу исполнения (beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite).

Управление позиционированием

Popper.js поддерживает динамическое обновление позиции через метод update():

popperInstance.update();

Он пересчитывает координаты, учитывая текущее положение референса и состояние окна. Для автоматической реактивности используется autoUpdate:

import { autoUpdate } from '@popperjs/core';

const cleanup = autoUpdate(reference, popper, () => {
  popperInstance.update();
});

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

Управление стилями и рендеринг

Popper.js применяет абсолютное позиционирование через стили top, left, transform. Для контроля можно использовать модификатор computeStyles:

{
  name: 'computeStyles',
  options: {
    gpuAcceleration: true, // использование GPU-трансформаций
    adaptive: true, // адаптивная корректировка под размеры окна
  },
}

Особенности:

  • gpuAcceleration: true снижает нагрузку на CPU при перемещении элементов.
  • adaptive: true корректирует позицию при изменении размеров окна и скроллинге.

Интеграция с фреймворками

Popper.js легко интегрируется с React, Vue и Angular. Для React существует обертка react-popper:

import { usePopper } from 'react-popper';

const { styles, attributes } = usePopper(referenceElement, popperElement, {
  placement: 'bottom-start',
});

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

Работа с динамическим контентом

Popper.js автоматически отслеживает изменения размеров референса и поппера. Для случаев динамического контента важно:

  • Пересчитывать позицию при изменении содержимого.
  • Использовать ResizeObserver или встроенный механизм autoUpdate.
  • Правильно обрабатывать смещение стрелки через модификатор arrow.

Пример с динамическим контентом:

const observer = new ResizeObserver(() => {
  popperInstance.update();
});
observer.observe(popper);
observer.observe(reference);

Оптимизация производительности

Popper.js рассчитан на высокую производительность, но при сложных интерфейсах стоит учитывать:

  • Минимальное количество модификаторов.
  • Использование gpuAcceleration.
  • Очистку слушателей через cleanup после удаления элементов.
  • Ограничение частоты вызова update() при анимациях через requestAnimationFrame или throttle.

Практические рекомендации

  • Всегда задавать placement и модификаторы для стабильного позиционирования.
  • Для адаптивных интерфейсов включать flip и preventOverflow.
  • Для всплывающих подсказок с динамическим контентом использовать autoUpdate и ResizeObserver.
  • Модификаторы кастомизировать только при необходимости, чтобы избежать конфликтов с базовыми.

Popper.js обеспечивает надежное позиционирование элементов в веб-интерфейсах и позволяет гибко управлять поведением всплывающих элементов без сложных ручных вычислений координат и учёта ограничений контейнеров.