Динамическое создание секций

Библиотека fullPage.js изначально ориентирована на статическую разметку, где каждая секция (.section) заранее присутствует в DOM. Однако современные приложения требуют гибкости: загрузка контента с сервера, генерация интерфейса на основе пользовательских действий, ленивое добавление блоков. В таких случаях возникает необходимость динамического создания и удаления секций.

Ключевая особенность fullPage.js — внутреннее кэширование структуры страницы. Любые изменения DOM без уведомления библиотеки приводят к рассинхронизации: навигация ломается, якоря работают некорректно, прокрутка становится нестабильной. Поэтому работа с динамическими секциями требует использования встроенных методов API.


Метод addSection

Основной инструмент для добавления секций — метод fullpage_api.addSection().

Синтаксис:

fullpage_api.addSection(htmlString, index);

Параметры:

  • htmlString — строка HTML с разметкой новой секции
  • index — позиция вставки (необязательный параметр, по умолчанию — в конец)

Пример:

fullpage_api.addSection(`
    <div class="section">
        <h2>Новая секция</h2>
        <p>Динамически добавленный контент</p>
    </div>
`);

После выполнения метода:

  • секция добавляется в DOM
  • fullPage.js обновляет внутреннюю структуру
  • навигация автоматически перестраивается

Вставка секции в конкретную позицию

Добавление секции в середину структуры требует указания индекса:

fullpage_api.addSection(`
    <div class="section">
        <h2>Вставленная секция</h2>
    </div>
`, 2);

Индексация начинается с нуля:

  • 0 — первая секция
  • 1 — вторая и т.д.

При вставке:

  • последующие секции смещаются
  • якоря и индексы пересчитываются

Динамическое удаление секций

Для удаления используется метод:

fullpage_api.removeSection(index);

Пример:

fullpage_api.removeSection(1);

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

  • удаление происходит мгновенно
  • если удаляется текущая секция, активной становится соседняя
  • навигация автоматически обновляется

Генерация секций на основе данных

Частый сценарий — создание секций из массива данных:

const sectionsData = [
    { title: "Секция 1", content: "Контент 1" },
    { title: "Секция 2", content: "Контент 2" }
];

sectionsData.forEach(item => {
    fullpage_api.addSection(`
        <div class="section">
            <h2>${item.title}</h2>
            <p>${item.content}</p>
        </div>
    `);
});

Подход применяется при:

  • загрузке данных через API
  • генерации страниц в SPA
  • построении лендингов на основе CMS

Повторная инициализация vs динамическое добавление

Существует альтернативный подход — полная пересборка:

fullpage_api.destroy('all');

// изменение DOM вручную

new fullpage('#fullpage', options);

Сравнение подходов:

Подход Преимущества Недостатки
addSection Быстро, без перезапуска Ограниченная гибкость
destroy + init Полный контроль Потеря состояния, дорого по ресурсам

Предпочтение отдается addSection, если не требуется радикальное изменение структуры.


Работа с якорями при динамическом создании

Для корректной навигации используются якоря (anchors):

fullpage_api.addSection(`
    <div class="section" data-anchor="dynamic">
        <h2>С якорем</h2>
    </div>
`);

После добавления:

  • доступна навигация по URL: #dynamic
  • можно использовать метод:
fullpage_api.moveTo('dynamic');

Важно:

  • якоря должны быть уникальными
  • дублирование приводит к ошибкам навигации

Обновление после ручных изменений DOM

Если секция добавляется без использования API (например, через appendChild), необходимо вызвать:

fullpage_api.reBuild();

Этот метод:

  • пересчитывает размеры
  • обновляет позиции
  • синхронизирует DOM с внутренним состоянием

Однако такой подход менее надежен, чем addSection.


Ленивая загрузка секций

Оптимизация производительности достигается через отложенное добавление:

document.addEventListener('scroll', () => {
    if (условие) {
        fullpage_api.addSection(`
            <div class="section">
                <h2>Поздняя загрузка</h2>
            </div>
        `);
    }
});

Применяется при:

  • больших лендингах
  • медленных API
  • необходимости ускорить initial render

Динамическое добавление горизонтальных слайдов

Помимо вертикальных секций, поддерживаются слайды (.slide):

fullpage_api.addSlide(htmlString, sectionIndex, slideIndex);

Пример:

fullpage_api.addSlide(`
    <div class="slide">
        <h3>Новый слайд</h3>
    </div>
`, 0, 1);

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

После добавления секций важно учитывать:

  • текущая позиция пользователя
  • активные классы (active)
  • состояние анимаций

Иногда требуется принудительное обновление:

fullpage_api.moveTo(fullpage_api.getActiveSection().index);

Частые ошибки

1. Добавление без класса .section

<div>...</div> <!-- не будет распознано -->

2. Прямое изменение DOM без reBuild()

3. Дублирование якорей

4. Нарушение структуры вложенности

Правильная структура:

<div id="fullpage">
    <div class="section">
        <div class="slide">...</div>
    </div>
</div>

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

В React/Vue динамика часто реализуется через состояние:

React пример:

useEffect(() => {
    new fullpage('#fullpage', options);
}, []);

useEffect(() => {
    fullpage_api.reBuild();
}, [sections]);

Ключевая идея:

  • изменения состояния → изменение DOM → синхронизация с fullPage.js

Производительность и ограничения

При большом количестве динамических секций:

  • увеличивается нагрузка на reflow/repaint
  • ухудшается плавность прокрутки

Рекомендуется:

  • ограничивать количество секций
  • использовать lazy loading
  • избегать частых вызовов reBuild()

События при работе с динамическими секциями

После добавления секций продолжают работать стандартные события:

new fullpage('#fullpage', {
    afterLoad: function(origin, destination) {
        console.log(destination.index);
    }
});

Новые секции автоматически участвуют в жизненном цикле.


Практический шаблон динамической системы

function createSection(title, content) {
    return `
        <div class="section">
            <h2>${title}</h2>
            <p>${content}</p>
        </div>
    `;
}

function addNewSection(data) {
    const html = createSection(data.title, data.content);
    fullpage_api.addSection(html);
}

Такой подход:

  • изолирует генерацию HTML
  • упрощает масштабирование
  • повышает читаемость кода