Корректная инициализация и стабильная работа библиотеки Headroom.js напрямую зависят от валидности передаваемых параметров. Несмотря на то, что сама библиотека достаточно устойчива к ошибкам, отсутствие явной проверки может привести к непредсказуемому поведению: некорректному скрытию/появлению элемента, «дёрганию» интерфейса или полной неработоспособности.
Проверка входных данных позволяет:
При создании экземпляра Headroom используются два ключевых аргумента:
const headroom = new Headroom(element, options);
element — DOM-элемент, к которому применяется
поведение;options — объект конфигурации.Каждый из них требует отдельной проверки.
Первое, что необходимо проверить — наличие и корректность элемента:
if (!element) {
throw new Error("Headroom: элемент не передан");
}
if (!(element instanceof HTMLElement)) {
throw new TypeError("Headroom: передан некорректный DOM-элемент");
}
null или undefined"#header" вместо
document.querySelector)NodeList,
HTMLCollection)const element = document.querySelector("header");
if (!element) {
console.warn("Header не найден");
} else {
const headroom = new Headroom(element);
headroom.init();
}
Параметр options является необязательным, но при его
наличии требуется убедиться, что это объект:
if (options && typeof options !== "object") {
throw new TypeError("Headroom: options должен быть объектом");
}
Определяет, на каком расстоянии от верхней границы страницы начинается реакция.
if (options.offset !== undefined) {
if (typeof options.offset !== "number" || options.offset < 0) {
throw new TypeError("offset должен быть неотрицательным числом");
}
}
Допускается также объект:
if (typeof options.offset === "object") {
if (typeof options.offset.up !== "number" || typeof options.offset.down !== "number") {
throw new TypeError("offset.up и offset.down должны быть числами");
}
}
Определяет чувствительность к прокрутке.
if (options.tolerance !== undefined) {
const tol = options.tolerance;
if (typeof tol === "number") {
if (tol < 0) {
throw new Error("tolerance не может быть отрицательным");
}
} else if (typeof tol === "object") {
if (typeof tol.up !== "number" || typeof tol.down !== "number") {
throw new TypeError("tolerance.up и tolerance.down должны быть числами");
}
} else {
throw new TypeError("tolerance должен быть числом или объектом");
}
}
Позволяет переопределить CSS-классы.
if (options.classes !== undefined) {
if (typeof options.classes !== "object") {
throw new TypeError("classes должен быть объектом");
}
Object.values(options.classes).forEach(className => {
if (typeof className !== "string") {
throw new TypeError("имена классов должны быть строками");
}
});
}
Определяет контейнер прокрутки.
if (options.scroller !== undefined) {
if (
!(options.scroller instanceof HTMLElement) &&
options.scroller !== window
) {
throw new TypeError("scroller должен быть HTMLElement или window");
}
}
Headroom поддерживает ряд callback-функций:
onPinonUnpinonToponNotToponBottomonNotBottomПроверка:
const callbacks = [
"onPin",
"onUnpin",
"onTop",
"onNotTop",
"onBottom",
"onNotBottom"
];
callbacks.forEach(cb => {
if (options[cb] !== undefined && typeof options[cb] !== "function") {
throw new TypeError(`${cb} должен быть функцией`);
}
});
Подходит для разработки:
throw new Error("Некорректный параметр");
Подходит для production:
console.warn("Некорректный параметр, используется значение по умолчанию");
const defaultOptions = {
offset: 0,
tolerance: 0
};
options = { ...defaultOptions, ...options };
Создание отдельной функции упрощает повторное использование:
function validateHeadroomOptions(element, options = {}) {
if (!(element instanceof HTMLElement)) {
throw new Error("Некорректный элемент");
}
if (typeof options !== "object") {
throw new Error("options должен быть объектом");
}
// Проверка offset
if (options.offset && typeof options.offset !== "number") {
throw new Error("offset должен быть числом");
}
// Проверка tolerance
if (options.tolerance && typeof options.tolerance !== "number") {
throw new Error("tolerance должен быть числом");
}
return true;
}
Использование:
validateHeadroomOptions(element, options);
const headroom = new Headroom(element, options);
При использовании TypeScript проверка частично переносится на этап компиляции:
interface HeadroomOptions {
offset?: number | { up: number; down: number };
tolerance?: number | { up: number; down: number };
classes?: Record<string, string>;
scroller?: HTMLElement | Window;
}
Однако runtime-проверка остаётся необходимой, так как данные могут поступать из внешних источников.
undefined is not a functionfunction initHeadroom(selector, options) {
const element = document.querySelector(selector);
if (!element) {
console.warn("Элемент не найден:", selector);
return;
}
try {
validateHeadroomOptions(element, options);
const headroom = new Headroom(element, options);
headroom.init();
} catch (e) {
console.error("Ошибка инициализации Headroom:", e.message);
}
}
В сложных приложениях может использоваться схема-валидация:
function isNumber(value) {
return typeof value === "number" && !isNaN(value);
}
function validateOffset(offset) {
if (isNumber(offset)) return true;
if (
typeof offset === "object" &&
isNumber(offset.up) &&
isNumber(offset.down)
) {
return true;
}
return false;
}
Такая последовательность обеспечивает максимальную устойчивость и предсказуемость поведения Headroom.js в любых условиях эксплуатации.