SortableJS — это мощная библиотека для реализации перетаскивания
элементов в списках на веб-страницах. Одним из ключевых аспектов работы
с SortableJS является правильное понимание контекста выполнения
обработчиков событий и особенностей this внутри
них.
this в
обработчикахВ SortableJS обработчики событий, такие как onStart,
onEnd, onAdd, onUpdate и другие,
вызываются в контексте экземпляра Sortable, если не
применены стрелочные функции.
Пример стандартного подхода:
const list = document.getElementById('items');
const sortable = new Sortable(list, {
onStart: function (evt) {
console.log(this); // Sortable instance
console.log(evt.item); // элемент, который начал перетаскиваться
}
});
this внутри обычной функции указывает на
текущий экземпляр Sortable.evt.item — это DOM-элемент, с которым пользователь
начал взаимодействие.evt.from — исходный контейнер списка.evt.to — конечный контейнер, если элемент был перемещён
между списками.evt.oldIndex и evt.newIndex — позиции
элемента до и после перемещения.Использование стрелочных функций меняет поведение
this:
const sortable = new Sortable(list, {
onEnd: (evt) => {
console.log(this); // Не Sortable, а контекст внешней области видимости
}
});
Стрелочные функции не имеют собственного
this, что может быть полезно для замыкания на
внешние переменные, но нужно помнить, что доступ к экземпляру Sortable
через this будет невозможен.
Каждый обработчик получает объект события с детальной информацией. Основные свойства:
item — элемент, над которым происходит действие.from — контейнер, из которого был извлечён
элемент.to — контейнер, в который помещается элемент.oldIndex — индекс элемента до перемещения.newIndex — индекс элемента после перемещения.clone — если включён режим копирования, содержит клон
перемещаемого элемента.pullMode — режим “pull” для сортировки между
списками.originalEvent — оригинальное DOM-событие
mousedown или touchstart.Эти свойства позволяют создавать гибкие обработчики, учитывающие любые сценарии перетаскивания.
Когда используется несколько списков с опцией group,
контекст выполнения может включать элементы разных контейнеров:
const listA = document.getElementById('listA');
const listB = document.getElementById('listB');
new Sortable(listA, {
group: 'shared',
onAdd: function(evt) {
console.log(evt.from.id); // id исходного списка
console.log(evt.to.id); // id целевого списка
console.log(evt.item.textContent); // содержимое перемещённого элемента
}
});
new Sortable(listB, {
group: 'shared'
});
onAdd вызывается только у целевого контейнера, куда
добавлен элемент.onRemove вызывается у исходного контейнера.this в обоих случаях соответствует экземпляру
того контейнера, где сработал обработчик.Для передачи дополнительного состояния внутрь обработчиков можно
использовать замыкания или bind:
const contextData = { userId: 42 };
const sortable = new Sortable(list, {
onEnd: function(evt) {
console.log(this); // Sortable instance
console.log(contextData); // пользовательский контекст
}.bind(contextData) // изменяет this на contextData
});
При использовании bind this перестаёт
ссылаться на Sortable и указывает на переданный объект. Это может быть
полезно для интеграции с приложением, где нужно хранить состояние
пользователя или другого объекта.
SortableJS позволяет использовать асинхронные операции в
обработчиках. Контекст this сохраняется в пределах функции,
но доступ к экземпляру через стрелочную функцию будет потерян:
const sortable = new Sortable(list, {
onEnd: async function(evt) {
await fetch('/update-order', {
method: 'POST',
body: JSON.stringify({ oldIndex: evt.oldIndex, newIndex: evt.newIndex })
});
console.log(this); // Sortable instance
}
});
Асинхронная функция корректно работает с объектом события и сохраняет
контекст экземпляра при использовании обычной функции. Стрелочные
функции здесь использовать не рекомендуется, если необходим
this для Sortable.
this указывает на
экземпляр Sortable, доступ к свойствам библиотеки.this — внешний
контекст, удобен для замыканий и доступа к внешним переменным.onAdd и onRemove вызываются только
у контейнеров, где произошло добавление или удаление.bind.Контроль контекста выполнения является ключевым для корректной работы сложных интерактивных интерфейсов на базе SortableJS, особенно при взаимодействии нескольких списков и асинхронных операций.