Interact.js предоставляет мощный инструмент для создания интерактивных элементов на странице, таких как перетаскивание, масштабирование и поворот. Когда речь идёт о большом количестве элементов, необходимо учитывать производительность, управление событиями и структуру кода, чтобы взаимодействие оставалось плавным.
Вместо того чтобы привязывать обработчики к каждому элементу индивидуально, используется селекторное делегирование:
interact('.draggable')
.draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
listeners: {
move (event) {
const target = event.target;
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
target.style.transform = `translate(${x}px, ${y}px)`;
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
}
});
Преимущества такого подхода:
Для оптимизации рекомендуется объединять элементы в контейнеры и обрабатывать события на уровне контейнера:
const container = document.getElementById('container');
interact(container)
.on('dragmove', event => {
const target = event.target.closest('.draggable');
if (!target) return;
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
target.style.transform = `translate(${x}px, ${y}px)`;
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
});
Такой подход позволяет:
При работе с сотнями или тысячами интерактивных объектов важно учитывать оптимизацию:
modifiers: [
interact.modifiers.restrictRect({ restriction: 'parent', endOnly: true })
]
requestAnimationFrame
Для обновления стилей лучше использовать цикл
requestAnimationFrame, чтобы синхронизировать рендеринг с
кадрами браузера:let ticking = false;
function updateTransform(target, x, y) {
if (!ticking) {
requestAnimationFrame(() => {
target.style.transform = `translate(${x}px, ${y}px)`;
ticking = false;
});
ticking = true;
}
}
Interact.js позволяет автоматически работать с элементами, добавленными после инициализации:
document.getElementById('add-element').addEventListener('click', () => {
const newElement = document.createElement('div');
newElement.classList.add('draggable');
container.appendChild(newElement);
interact(newElement).draggable({ /* параметры */ });
});
Чтобы избежать инициализации каждого нового элемента вручную, можно использовать селекторную привязку:
interact('.draggable').draggable({ listeners: { move: dragMoveListener } });
Это автоматически охватывает все текущие и будущие элементы с
классом .draggable.
Иногда требуется перемещать или трансформировать сразу несколько элементов одновременно:
const selectedElements = document.querySelectorAll('.selected');
function dragGroup(event) {
selectedElements.forEach(target => {
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
target.style.transform = `translate(${x}px, ${y}px)`;
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
});
}
interact('.group-draggable').draggable({
listeners: { move: dragGroup }
});
Особенности:
Для плавного взаимодействия с множеством объектов рекомендуется:
restrictRect.interact('.draggable').draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
]
});
Эти подходы обеспечивают плавное и эффективное управление сотнями и тысячами интерактивных объектов на странице при использовании Interact.js.