Рефакторинг кода, использующего Smooth Scroll, начинается с детального анализа существующей реализации. Основное внимание уделяется:
Типичный пример «сырого» кода:
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
beh * avior: 'smooth'
});
});
});
Недостатки:
Жестко заданные параметры следует вынести в конфигурационный объект. Это упрощает поддержку и масштабирование.
const scrollConfig = {
selector: 'a[href^="#"]',
beh * avior: 'smooth',
block: 'start'
};
Использование:
document.querySelectorAll(scrollConfig.selector).forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (!target) return;
target.scrollIntoView({
beh * avior: scrollConfig.behavior,
block: scrollConfig.block
});
});
});
Преимущества:
Разрозненный код заменяется модульной структурой. Логика прокрутки выносится в отдельную функцию или класс.
function smoothScrollTo(targetSelector, options = {}) {
const element = document.querySelector(targetSelector);
if (!element) return;
element.scrollIntoView({
beh * avior: options.behavior || 'smooth',
block: options.block || 'start'
});
}
Использование:
document.addEventListener('click', function (e) {
const anchor = e.target.closest('a[href^="#"]');
if (!anchor) return;
e.preventDefault();
smoothScrollTo(anchor.getAttribute('href'));
});
Преимущества:
Вместо навешивания обработчика на каждый элемент используется делегирование:
document.addEventListener('click', function (e) {
const link = e.target.closest('a[href^="#"]');
if (!link) return;
e.preventDefault();
const targetId = link.getAttribute('href');
const target = document.querySelector(targetId);
if (!target) return;
target.scrollIntoView({ beh * avior: 'smooth' });
});
Преимущества:
При использовании сторонней библиотеки (например, Smooth Scroll), часто встречается неструктурированная инициализация:
var scroll = new SmoothScroll('a[href*="#"]', {
speed: 300
});
Рефакторинг предполагает:
const smoothOptions = {
speed: 500,
offset: 80,
easing: 'easeInOutCubic'
};
function initSmoothScroll(options) {
return new SmoothScroll('a[href*="#"]', options);
}
const scrollInstance = initSmoothScroll(smoothOptions);
Часто в коде встречаются «магические числа»:
offset: 80
Рефакторинг:
const HEADER_HEIGHT = 80;
const smoothOptions = {
speed: 500,
offset: HEADER_HEIGHT
};
Преимущества:
Смешивание логики прокрутки и UI-логики ухудшает поддержку:
Плохой пример:
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.body.classList.remove('menu-open');
document.querySelector(this.getAttribute('href')).scrollIntoView({
beh * avior: 'smooth'
});
});
Рефакторинг:
function closeMenu() {
document.body.classList.remove('menu-open');
}
function handleAnchorClick(e) {
const link = e.target.closest('a[href^="#"]');
if (!link) return;
e.preventDefault();
closeMenu();
smoothScrollTo(link.getAttribute('href'));
}
document.addEventListener('click', handleAnchorClick);
Преимущества:
Рефакторинг должен учитывать нестандартные ситуации:
function smoothScrollTo(selector) {
if (!selector || selector === '#') return;
const element = document.querySelector(selector);
if (!element) {
console.warn(`Элемент ${selector} не найден`);
return;
}
element.scrollIntoView({ beh * avior: 'smooth' });
}
Добавляется:
const anchors = document.querySelectorAll('a[href^="#"]');
Лучше:
const cache = new Map();
function getElement(selector) {
if (!cache.has(selector)) {
cache.set(selector, document.querySelector(selector));
}
return cache.get(selector);
}
Добавление возможности переопределения параметров:
function createSmoothScroll(customOptions = {}) {
const defaultOptions = {
speed: 500,
offset: 0
};
const options = { ...defaultOptions, ...customOptions };
return new SmoothScroll('a[href*="#"]', options);
}
При усложнении логики предпочтителен объектно-ориентированный подход:
class SmoothScrollManager {
constructor(options = {}) {
this.options = {
speed: 500,
offset: 0,
...options
};
this.instance = null;
}
init() {
this.instance = new SmoothScroll('a[href*="#"]', this.options);
}
destroy() {
if (this.instance) {
this.instance.destroy();
this.instance = null;
}
}
update(options) {
this.destroy();
this.options = { ...this.options, ...options };
this.init();
}
}
Преимущества:
Код после рефакторинга становится: