Dojo dnd: позиционирование аватара - PullRequest
4 голосов
/ 03 августа 2009

Можно ли изменить положение аватара с помощью dnd api инструментария dojo? В данный момент при перетаскивании аватар перетаскиваемого элемента появляется справа и ниже курсора мыши. Я хочу, чтобы он был в том же положении, что и курсор мыши. Я выполнил несколько тестов юзабилити своего приложения, и большинство людей, похоже, пытаются перетащить аватар в область перетаскивания, а не перемещать курсор над областью перетаскивания. Любой вклад был бы хорош. Спасибо!

1 Ответ

6 голосов
/ 04 августа 2009

Извините, по техническим причинам это невозможно.

ОБНОВЛЕНИЕ: по многочисленным просьбам это технические причины:

  • Когда у вас есть узел прямо под мышью, узел получает все события мыши.
  • События мыши всплывают в родительской цепочке.
  • Теперь представьте, что вы перемещаете этот узел мышью & mdash; этот узел всегда будет получать все события мыши.
  • Это означает, что любой другой узел, например цель, не может получать события мыши, если он не является родителем перемещенного узла. Обычно это не так.

Но я знаю, что другие люди могут это сделать! Это должно быть возможно! Да, это возможно & hellip; в принципе:

  • Давайте зарегистрируем все целевые узлы.
  • Давайте поймать соответствующие события перемещения мыши непосредственно на самом верхнем родительском элементе (документе).
  • Когда мы обнаружим операцию перетаскивания, сделаем следующее:
    1. Рассчитать геометрию (ограничивающие рамки) всех целей.
    2. При каждом движении мыши давайте проверим, перекрывается ли текущая позиция мыши с целью. Бонусные баллы для ученика «A +»: обнаружение совпадений с другими узлами, например, когда цель частично скрыта по косметическим соображениям, и правильная обработка этой ситуации.
    3. Если текущая позиция мыши перекрывается с целью, давайте запустим действия «выпадение возможно», например, покажем несколько подсказок, чтобы конечный пользователь знал, что она может упасть сейчас.

Почему Додзё этого не делает? По ряду технических причин (наконец-то мы туда попали!):

  • Расчет геометрии узла, как известно, глючит в большинстве браузеров. Как только будут задействованы таблицы или любые другие нетривиальные способы размещения, вы не можете быть на 100% уверены в правильности ограничивающего прямоугольника.
  • Расчет геометрии является дорогостоящей операцией, и мы должны выполнять ее как минимум один раз для каждой операции перетаскивания для всех целей, предполагая, что во время операции перетаскивания не может быть сделано никаких изменений (не всегда так). Браузер может перекомпоновывать узлы по многим причинам & rArr; он может перемещать / изменять размеры существующих целей, поэтому мы должны быть бдительными.
  • Обычно рассчитанные поля хранятся в списке & rArr; проверка списка пересечений - это O (n) (линейный) & rArr; плохо масштабируется, так как количество целей растет.
  • Все обработчики событий мыши должны быть быстрыми, в противном случае средство обработки событий мыши в браузере может быть «сломано», что приведет к непредсказуемым побочным эффектам. См. Предыдущие пункты о причинах, по которым обработка событий мыши может быть медленной.
  • Возможно улучшение линейного поиска, например, можно использовать 2D пространственные деревья, но это приводит к большему (гораздо большему) коду JavaScript & rArr; больше материалов для скачивания на стороне клиента & rArr; как правило, оно того не стоит.

Откуда мне это знать? Потому что у Dojo был такой вид drag'n'drop в более ранних версиях, и мы заболели и устали бороться с проблемами, которые я описал выше. Любое улучшение было тяжелым сражением, которое увеличивало размер кода. Наконец, мы решили не изобретать и не копировать механизмы, уже встроенные в браузер. Браузер выполняет практически ту же работу: вычисляет геометрию узлов, находит базовый узел и соответствующим образом отправляет событие перемещения мыши.

Текущая реализация не использует события перемещения мыши и не вычисляет геометрию. Вместо этого он опирается на события мыши / нахождения, обнаруженные целями после начала перетаскивания. Работает надежно и хорошо масштабируется.

Еще одна проблема в этой истории: Dojo рассматривает цели как контейнеры & mdash; очень распространенный вариант использования (корзины покупок, перестановка элементов, редактирование иерархий). В настоящее время реализованы линейные контейнеры и общие деревья, возможны пользовательские контейнеры. При перетаскивании вы можете видеть и перетаскивать перетаскиваемые элементы в нужном месте в целевом контейнере, например, вставляя их между существующими элементами. Реализация этой функции с использованием геометрических расчетов и проверок будет непомерно дорогой.

...