В SVG.js события играют ключевую роль в интерактивных приложениях, позволяя реагировать на действия пользователя, изменения состояния элементов или временные триггеры. Управление подписками на события включает не только их добавление, но и корректное удаление, чтобы избежать утечек памяти и конфликтов между обработчиками.
Для начала рассмотрим стандартный способ подписки:
const draw = SVG().addTo('body').size(300, 300);
const rect = draw.rect(100, 100).fill('blue');
function handleClick(event) {
console.log('Клик по прямоугольнику', event);
}
rect.on('click', handleClick);
Здесь метод on добавляет обработчик
handleClick к событию click. Важно, что
каждый вызов on создаёт отдельную ссылку на
обработчик, которую можно использовать для последующего
удаления.
offМетод off используется для удаления обработчиков
событий. Он поддерживает несколько вариантов применения:
rect.off('click', handleClick);
После выполнения этой команды клик по прямоугольнику больше не будет
вызывать handleClick. Если к событию было привязано
несколько функций, остальные останутся активными.
rect.off('click');
Все функции, подписанные на событие click для данного
элемента, будут отменены. Этот способ полезен, когда необходимо
полностью очистить обработчики перед изменением состояния элемента.
rect.off();
Метод без аргументов снимает все подписки на все события, зарегистрированные через SVG.js для данного элемента. Следует использовать осторожно, чтобы случайно не удалить важные обработчики.
Подписка на событие с именованной функцией
Использование анонимной функции затрудняет отмену подписки:
rect.on('mouseover', function(e) {
console.log('Наведение мыши');
});
// Такой обработчик удалить через off невозможно напрямую
rect.off('mouseover'); // удалит все обработчики mouseover
Для точного удаления необходимо использовать именованную функцию:
function handleMouseOver(e) {
console.log('Наведение мыши');
}
rect.on('mouseover', handleMouseOver);
rect.off('mouseover', handleMouseOver);
Подписка на несколько событий одновременно
Метод on поддерживает массив событий:
function logEvent(e) { console.log(e.type); }
rect.on(['mouseenter', 'mouseleave'], logEvent);
Удаление конкретного обработчика выполняется аналогично:
rect.off(['mouseenter', 'mouseleave'], logEvent);
SVG.js позволяет работать с группами элементов
(<g>). Подписка на событие группы не распространяется
автоматически на дочерние элементы. Если требуется делегирование,
следует подписываться на каждый элемент индивидуально. Отмена подписки
также производится на конкретном элементе.
const group = draw.group();
const circle = group.circle(50).fill('red');
circle.on('click', handleClick);
circle.off('click', handleClick);
offoff работает только с обработчиками, добавленными через
on. События, назначенные через нативный
addEventListener, не будут сняты этим методом.rect.remove();
rect.off(); // очистка всех подписок
off возвращает сам элемент, что позволяет
использовать цепочку вызовов:rect.off('click', handleClick).fill('green').stroke({ width: 2 });
В интерфейсах, где элементы создаются и уничтожаются динамически, правильное управление подписками критично. Часто используют шаблон добавления обработчиков при создании элемента и их удаления перед удалением элемента. Это гарантирует отсутствие “висячих” обработчиков, которые могут приводить к неожиданным ошибкам.
function createButton(label) {
const btn = draw.rect(100, 50).fill('orange');
function onClick() { console.log(label); }
btn.on('click', onClick);
btn.removeWithEvents = () => {
btn.off('click', onClick);
btn.remove();
}
return btn;
}
const myButton = createButton('Test');
myButton.removeWithEvents(); // безопасное удаление
SVG.js предоставляет гибкий и безопасный механизм управления
событиями через on и off. Чёткое понимание
этих методов позволяет строить динамичные, интерактивные графические
интерфейсы без риска утечек памяти и конфликтов обработчиков.