Некоторое время назад я писал о том, что пишу некий
«аналог jQuery Treeview». Благодаря подсказке
nikitammf проблему «отпрыгивающего элемента» я поборол.
Но появилась другая проблема. Чтобы описать её, я сначала объясню каким образом плагин jQuery UI Draggable определяет находится ли в данный момент переносимый элемент над droppable-элементом.
В момент начала переноса захваченного элемента вызывается метод
$.ui.ddmanager.prepareOffsets(this, event)
(строка 152 файла /development-bundle/ui/jquery.ui.draggable.js). Этот метод запоминает в кэше абсолютные координаты всех droppable-элементов. Затем в процессе переноса draggable-элемента, его меняющиеся координаты постоянно сверяются с координатами droppable-элементов из кэша, и когда наступает пересечение координат — плагин опознаёт, что захваченный элемент оказался над тем-то droppable-элементом (т.е. наступает событие
«hover»). Кэш координат droppable-элементов всегда рассчитывается только один раз — в момент начала переноса захваченного элемента.
Как это конфликтует с моим кодом? Как я уже писал, в момент наступления события
«hover» у меня отсылается запрос на сервер, который возвращает список дочерних элементов, которые вставляются вложенным списком. Поскольку вставляется вложенный список, координаты последующих (лежащих ниже) droppable-элементов при этом меняются, но кэш координат об этом не знает.
В результате если захватить самый первый элемент, задержать над вторым элементом (дождавшись появления вложенного списка) и дальше вести его вниз, то третий и последующий элементы среагируют ещё задолго до того, как перетаскиваемый элемент реально окажется над ними (потому что в кэше координат остались старые координаты и он по-прежнему думает, что все droppable-элементы остались на своих изначальных местах).
Как решить эту проблему, впринципе понятно: пересчитать кэш координат (вызвать метод
$.ui.ddmanager.prepareOffsets(this, event)
) после вставки дочернего списка.
Но так просто вызвать этот метод не получается: его имя уже изменено в процессе компоновки и минимизации конструктором jQuery UI (я использую не гигантский архив с кучей js-файлов, а собранный
конструктором один файл).
Как здесь быть? Как вызвать метод, имя которого уже «обфусцировано»?
Онлайн-пример собственно моей разработки
тут.