Stickybits — это лёгкая библиотека для создания «липких» элементов на странице, которая обеспечивает кроссбраузерную поддержку и адаптацию к различным устройствам. Базовое поведение библиотеки можно расширять с помощью собственных модулей и плагинов. Основная идея создания расширений заключается в добавлении кастомного поведения на этапах жизненного цикла элемента: инициализация, фиксация, отпускание и разрушение.
Библиотека предоставляет объект Stickybits с методом
addInstance и хуками, которые позволяют внедрять
собственные функции в процесс работы с элементами.
import Stickybits from 'stickybits';
const stickyInstance = Stickybits('.sticky', {
stickyBitStickyOffset: 20,
useStickyClasses: true,
});
Параметры конфигурации, которые могут понадобиться для расширений:
stickyBitStickyOffset — смещение элемента от верхнего
края окна при фиксации.useStickyClasses — добавляет CSS-классы
is-sticky и is-stuck для управления
состояниями элемента.noStyles — отключает встроенные стили Stickybits, чтобы
полностью контролировать внешний вид через CSS.Для расширений важно уметь отслеживать эти состояния и реагировать на смену класса элемента.
Stickybits предоставляет несколько ключевых точек, в которые можно подключать свои функции:
onStickyStateChange — вызывается при
смене состояния элемента (default, sticky,
stuck).onPositionChange — вызывается при
каждом пересчёте позиции элемента на странице.onResize — срабатывает при изменении
размера окна, что важно для адаптивных решений.Пример подключения собственного хука:
stickyInstance.forEach(instance => {
instance.el.addEventListener('stickyStateChange', (event) => {
console.log(`Состояние элемента: ${event.detail.state}`);
});
});
Здесь event.detail.state может принимать значения:
default, sticky, stuck.
Расширение Stickybits — это функция, которая принимает объект
instance и возвращает модифицированную версию с
дополнительными методами или событиями. Простейшая структура
расширения:
function myExtension(instance) {
const originalMethod = instance.update;
instance.update = function() {
// Дополнительная логика перед обновлением позиции
console.log('Перед обновлением позиции');
// Вызов оригинального метода
originalMethod.call(instance);
// Логика после обновления
console.log('После обновления позиции');
};
return instance;
}
Применение расширения:
const stickyWithExtension = Stickybits('.sticky', { useStickyClasses: true });
stickyWithExtension.forEach(instance => {
myExtension(instance);
});
Таким образом можно добавлять анимацию, логирование, адаптивные стили или взаимодействие с другими библиотеками без изменения исходного кода Stickybits.
function animateOnSticky(instance) {
instance.el.addEventListener('stickyStateChange', (e) => {
if (e.detail.state === 'sticky') {
instance.el.style.transition = 'transform 0.3s ease';
instance.el.style.transform = 'scale(1.05)';
} else {
instance.el.style.transform = 'scale(1)';
}
});
}
function logPosition(instance) {
instance.el.addEventListener('onPositionChange', () => {
console.log(`Элемент находится на ${instance.el.getBoundingClientRect().top}px от верхнего края`);
});
}
function syncWithScrollLibrary(instance, scrollLib) {
instance.el.addEventListener('stickyStateChange', (e) => {
if (e.detail.state === 'stuck') {
scrollLib.pause();
} else {
scrollLib.resume();
}
});
}
.call() — это позволяет сохранить базовую
функциональность.Подход Stickybits позволяет строить гибкие, модульные решения, при которых каждое расширение инкапсулирует отдельную функциональность. Такой способ интеграции обеспечивает поддержку различных проектов, упрощает тестирование и ускоряет разработку сложных интерфейсов с «липкими» элементами, сохраняя при этом чистоту кода и совместимость с основной библиотекой.