Interact.js предоставляет мощный механизм для создания интерактивных элементов с поддержкой перетаскивания, масштабирования и жестов. Ключевым аспектом при работе с большими приложениями является изоляция контекста — способность управлять поведением отдельных элементов без влияния на глобальные настройки или другие интерактивные объекты.
Изоляция контекста достигается за счёт создания отдельных экземпляров Interactable для каждого элемента или группы элементов, а также использования scope для разделения событий и настроек.
Каждый элемент, к которому необходимо применить интерактивное поведение, должен быть представлен отдельным объектом Interactable:
const draggableItem = interact('.draggable');
draggableItem.draggable({
listeners: {
start (event) {
console.log('Начало перетаскивания', event.target);
},
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);
}
},
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent'
})
],
inertia: true
});
Ключевые моменты:
interact(selector) создаёт отдельный
контекст для элемента.modifiers) применяются только
к этому экземпляру.listeners) изолированы, что предотвращает
конфликты с другими элементами.Interact.js позволяет создавать раздельные области
(scope), чтобы события и настройки одного набора
элементов не пересекались с другим:
const scopeA = interact.scope.new();
const boxA = scopeA.interact('.box-a');
boxA.draggable({
listeners: { move: event => console.log('Box A двигается') }
});
const scopeB = interact.scope.new();
const boxB = scopeB.interact('.box-b');
boxB.draggable({
listeners: { move: event => console.log('Box B двигается') }
});
Преимущества подхода с scope:
Модификаторы Interact.js, такие как restrictRect,
snap и restrictEdges, применяются к
конкретному объекту Interactable и не влияют на другие элементы, даже
если они используют аналогичные настройки:
interact('.resizable').resizable({
edges: { left: true, right: true, bottom: true, top: true },
modifiers: [
interact.modifiers.snapSize({
targets: [interact.snappers.grid({ width: 20, height: 20 })]
}),
interact.modifiers.restrictSize({
min: { width: 50, height: 50 },
max: { width: 300, height: 300 }
})
],
inertia: true
});
Особенности изоляции модификаторов:
Для сложных интерфейсов часто требуется объединять разные интерактивные действия на одном элементе. Использование отдельного Interactable обеспечивает безопасную комбинацию:
const panel = interact('.panel');
panel.draggable({
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);
}
}
});
panel.resizable({
edges: { left: true, right: true, bottom: true, top: true },
modifiers: [
interact.modifiers.restrictEdges({
outer: 'parent'
}),
interact.modifiers.restrictSize({
min: { width: 100, height: 100 },
max: { width: 600, height: 400 }
})
],
inertia: true
});
Выводы по изоляции:
scope для разделения контекста событий в
сложных приложениях.data-
атрибутах или отдельной модели данных для обеспечения
независимости.Изоляция контекста в Interact.js позволяет строить сложные интерфейсы с большим количеством интерактивных элементов без риска конфликтов и с полной управляемостью поведения каждого объекта.