| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > JavaScript: Общие вопросы > эффект перетаскивания объекта |
| Автор: Alx 11.2.2006, 19:12 |
| чё-то не соображу, можно сделать? ведь, насколько я знаю, нет события на отпускание кнопки мыши? у меня получилось сделать только так: click -> объект прилипает к курсору -> mousemove -> двигаем объект -> click -> кладем его еси мона как в системных приложених, подскажите, плиз! пасиб) |
| Автор: Innuendo 11.2.2006, 19:45 | ||
| Я когда-то делал див, который можно перетаскивать. структура такая: при ведении мыкшой по документа див идёт за курсором. Но только если переменная флаг положительна. Изначальна она отрицательная... при нажатии на кнопку мыши, она становится положительной, а при отпускании опять отрицательной. Вот что у меня вышло. В FireFox, IE6 работает. В Опере не пробовал
надо добавить ещё отмену выделения но в Мозилле н будет работать. |
| Автор: Innuendo 11.2.2006, 20:13 |
| у скрипта выше баг в ИЕ... когда тольок открыли страницу, и наводите на пространство правее текста, то он потом не отпустит. Это там проблемы в СSS(лучше засунуть внутль h4 спан, и все действия задать ему.. а он чтоб был по ширине и высоте как и h4) То есть JavaScript работает нормально, если будешь использовать свой css стиль то должно нормально пойти. |
| Автор: 12345c 11.2.2006, 21:19 | ||
Alx: я делал тоже так, но к этому надо отменить событие ondragstart :
Иначе drag-n-drop понимается как возможность перетащить картинку на другое окно и конфликтует. ondragstart было задумано не для таскания объектов по окну, а для таскания картинок, файлов и ссылок на окно и из него. Есть также onDrop, onDragOver, onDragEnter, onDragLeave (ie5+), onDragDrop (Gecko) |
| Автор: Aliance 11.2.2006, 22:25 |
| Вот замечательный пример из моей первой книжке от издательства O'reilly. |
| Автор: Innuendo 11.2.2006, 22:32 |
| Aliance, у меня скрипт не работает нив ИЕ, ни в ФФ |
| Автор: Alx 11.2.2006, 23:00 |
| балин!!!! я всю свою сознательную жизнь думал, что события onmouseup не существует!!!!! вот в чем проблема... вот ***... слов нет... даже не догадался в ман посмотреть... щас подкорректирую свой скрипт и выложу 12345c, про drag-n-drop, я знаю, только не понял, зачем отменять ondragstart? ведь мы никаких особых собитий не используем, только стандартные события и задания координат абсолютно позиционированного DIV`а, относительно курсора, не думаю, что должно конфликтовать... |
| Автор: 12345c 12.2.2006, 00:50 |
| А потому что если попытаешься таким способом тащить рисунок, браузер решит, что ты хочешь его в новом окне посмотреть. Вместе с mousemove инициируется dragstart. |
| Автор: Innuendo 12.2.2006, 14:07 |
| ухты.. забавная штука |
| Автор: 12345c 12.2.2006, 15:38 |
| Alx, Они таскаться должны? ничего не просходит. (ie, ff). |
| Автор: Innuendo 12.2.2006, 16:45 |
| там пару квадратиков... они тащаться.. можно перетакскивать поверх квадрата, а понизу нельзя |
| Автор: Alx 12.2.2006, 18:45 |
| 12345c, как это? у меня везде работает... ничего не понимаю... не пару квадратиков, а 5 больших, разноцветных прямоугольных равносторонних параллелограмма! не понял) по какому низу? можно где хочешь, просто на время перетаскивания они выскакивают поверх всех других, а при окончании становятся опять по порядку) но это почему-то только в ИЕ. видимо, другие браузеры не поддерживают свойство z-index. |
| Автор: Sardar 12.2.2006, 20:08 |
| Парни, угадайте сколько готовых решений найдуться если вверху, в поиске задать "drag drop" Xотя это не плохо изобретать колесо по новой во время обучения |
| Автор: 12345c 12.2.2006, 23:55 | ||
| Sardar, штук 5 нашлось разной степени готовности. А в сети ещё штук 5 статей с готовым решением. Ты где-то собирался сделать скрипт для общего пользования, так вот я тоже могу, если публика попросит > как это? у меня везде работает... ничего не понимаю... никак не работает, и разобрался почему - результат получается всегда нецелый, а стили этого не понимают. Но ладно не целый, он ещё и неправильный. Как можно obj.style.left = _left - parseInt(obj.style.width) / 2; ? (В left загонять width.) Для проверки вставь алерт:
Innuendo, а как у тебя заработало? |
| Автор: Innuendo 13.2.2006, 00:15 |
| 12345c, ну я просто нажал на ссылку в сообщении Alx'a.. FireFox 1.5.0... заработало |
| Автор: 12345c 13.2.2006, 02:59 |
| А, понятно. Я-то приведённый код смотрел. |
| Автор: Alx 13.2.2006, 07:46 | ||
вот этот код работает абсолютно замечательно, во всех браузерах
давай |
| Автор: 12345c 13.2.2006, 14:39 |
| О, вот стилей там не хватало., теперь работает (не везде, см. ниже). Критика: 1) событий не навешаешься на объекты, если их много, лучше перехват событий на документе с анализом класса; 2) нет никакой надобности иметь признаки таскаемости при каждом объекте - мышь одна. Поэтому is_moving может быть переменной окна. 3) не соблюдён принцип поднимания затронутых слоёв - они возвращаются на своё место по уровню z-index. (Кстати, в FF, Opera он не срабатывает, из-за setAttribute, что ли, или строку присваиваешь вместо числа.) Для соблюдения достаточно присваивать ему номер, на 1 больший, чем имеется, и оставлять такой(переменная zMax). 4) совершенно забыл, что позиция мыши в ie не e.pageX, а e.pageX+document.body.scrollLeft . |
| Автор: Alx 13.2.2006, 15:16 | ||
| 12345c, мдя, в принципе, согласен, сейчас подправлю кроме третьего, зачем ставить перетаскиваемый объект выше других? и потом, если z-index будет всё время расти, это тоже совсем не красиво. я наконец-то понял, вначале ты имел ввиду: > obj.style.left = parseInt( _left - parseInt(obj.style.width) / 2 );
а почему нельзя? Добавлено @ 15:19 хех, а с чего ты взял, что стили не понимают дробных чисел? у меня width и height по 105, на 2 - дробное и никаких проблем. поэтому оставляем как было Добавлено @ 15:22 да, правильно. надо же, а почему? |
| Автор: 12345c 13.2.2006, 16:23 | ||
| по аналогиис Windows на век юзера хватит
здесь понимают, я искал ошибку, когда не работал скрипт. А бордюры, насколько помню, нге понимают, или что-то ещё есть кривости понимания где-то . Проще по-естественному обращаться к атрибутам. |
| Автор: Alx 13.2.2006, 17:19 | ||
| ну вот, готово) http://soft.flyweb.in/small/drag.html 12345с + за критику
можно, конечно, сделать ещё прокрутку окна при попытке перетащить объект за пределы видимости, а также позиционирование курсора не по центру, а на месте захвата (только как я не знаю) и даже сделать возможность выделения, как в Windows, а затем передвигания всех выделенных объектов. только надо ли? |
| Автор: Innuendo 13.2.2006, 19:03 |
| в этом примере у объекта который выбираешь, меняется z-index получается... он становится верхним. Но вот бывает иногда глюк.. застопыривается квадратик... Когда курсор каким-то образом захоит за грани квадрата при драге.. Ну это бывает при быстром драге, но и при медленном тоже.. когда проводишь через квадратик (поверх) |
| Автор: Alx 13.2.2006, 19:13 | ||||||
ну 12345c предложил, мне чё, жалко чтоль?)
это не ко мне) а к разработчикам JavaScript. соображает он медленно, не успевает за курсором
неправда |
| Автор: Innuendo 13.2.2006, 19:22 |
| Alx, нп, верю, верю а про то что соображает долго.. может как-то сделать проверку, ну то есть отследить этот сбой, и чтоб квадратик догнал быстренько мышку (ну просто оказался под ней). |
| Автор: Alx 13.2.2006, 20:07 |
| Innuendo, ну да в принципе, повесить событие и на документ щас попробуем |
| Автор: 12345c 13.2.2006, 20:08 |
| Это не из-за z-index, а из-за mouseout, которое часто не появляется при очень быстрых движениях. Я тоже этим серьёзно не занимался, а надо бы придумать, как восстанавливать mouseout, если оно пропущено. Это нужно и в меню, и везде. Идея - ловить mousemove вне объекта и обнаруживать случай, когда mousemove на объекте перескочило на mousemove вне объекта. Для одиночного квадрата это несложно, а общая задача - когда сложная страница. Очень был бы полезный антиглючный скрипт. Да, плюсов пора и тебе подсыпать, скажи за что - примеров много по сети. Принцип такой, что запоминаешь позицию при нажатии, а потом отностельно её двигаешь. Сейчас напишу свой примерчик, сделанный с рабочего скрипта. |
| Автор: Alx 13.2.2006, 20:19 | ||||
дык а есть свойство, которое возвращает координату мышь относительно ноды? в ИЕ вроде нет. можно, ессно вычесть из координат курсора координаты объекта и всё ок) ну не знаю) тебе видней) Добавлено @ 20:21
а можно конкретней, какие ещё могут быть траблы кроме drag-n-drop? вот ты в меню говорил, конкретно, в какой момент? |
| Автор: 12345c 13.2.2006, 20:40 | ||
| то же самое - меню, которое должно закрываться при уходе мыши. Двигаешь мышь очень быстро - меню остаётся открытым. Вот код, таким обычно пользуются (кроссбраузерный), но в нём ещё много недостатков. Можем поработать над ними не спеша. (Что интересно, проблема срыва mouseout в FF решена - как ни двигай, не сорвёшь нажатую мышь с объекта.)
Недостатки: *) запретить в Опере onSelect при таскании; *) запретить onDragStart (если будет рисунок/ссылка в таскаемом поле); *) потеря mouseout в ie,opera; *) не использовать target (если будет наполнение объекта, его не схватишь за фон); Список можно и нужно продолжить. |
| Автор: Alx 13.2.2006, 20:50 |
| 12345c ну ты меня извини, но это почти точная копия моего кода |
| Автор: Innuendo 13.2.2006, 20:58 |
| Alx, а можно вопрос? частью какой программы является эти квадратики? просто интересно |
| Автор: 12345c 13.2.2006, 20:58 | ||
Ну да, никто из нас америк не открывает - предлагаю свой код для развития, потому что он кажется компактным и удобным (писал его примерно год назад для проекта с тасканием слоёв). Всё равно над многим здесь ещё работать. А чтобы всё было проработано и выложено в виде статьи, я тоже не встречал.
|
| Автор: Alx 13.2.2006, 21:00 | ||||||
| только в эксплорере выделяется содержимое дивов. я добали в свой скрипт захват в точке вот так:
Добавлено @ 21:05
в смысле, не понял? 12345c, а, так это твой код? Добавлено @ 21:06
вы шутите, да? |
| Автор: 12345c 13.2.2006, 21:06 | ||
Неудобно, потому что если объекты многократно вложены (в таблицы), то придётся делать цикл рекурсии по всем offsetParent, суммировать координаты обрамляющих слоёв. Правда , для absolute это может и не требоваться ... Код мой, на http://burime.org.ru/test1/karta2/ посмотри, как это всё с запретами драга и селекта работает. Там, сначала можешь таскать подсказки, а если выделишь чекбокс "Редактировать карту", то сможешь таскать и картинки. нет, в моём за начало берётся не разница ,а координаты мыши в момент клика. Но всё не важно. Давайте закончим флудить, надоело тратить время на такую ерунду, как общение |
| Автор: Alx 13.2.2006, 21:10 |
| 12345c, хех... абсолютно позиционированные, они и есть абсолютно позиционированные... у них нет родителей...а относительно позиционированных ты бы не передвинул ;) и в том скрипте, который ты выложил, так и делается...) Добавлено @ 21:11 не пойму, как там реализовано, что в лисе не слетают дивы? |
| Автор: Innuendo 13.2.2006, 21:32 |
| ну ты так изначально и хотел чтоб просто квадратики двигать? или это к примеру игра, и там нужен такой скрипт |
| Автор: Alx 13.2.2006, 21:33 |
| ну всё, у мя терь тож хватает где надо) щас буду думать как сделать, чтоб не слетало при rollover`е. Добавлено @ 21:35 Innuendo, ну ты Шерлок Холмс да, я собирался попытаться летом написать футбольный менеджер на PHP+JS, а это должна была быть функция расположения игроков на поле) |
| Автор: Innuendo 13.2.2006, 22:15 | ||
мне бы скорее эту курсовую с этими матрицами сдать |
| Автор: Alx 13.2.2006, 23:02 | ||
| ... и ещё теперь они во всех браузерах никогда не спадают с курсора с какой скоростью не мотать и везде, кроме Оперы запрещено выделение. вот тут "http://soft.flyweb.in/small/drag.html" в принципе, надо ещё сделать чтобы - в опере не выделялось - проход по родительским элементам на предмен нахождения className == "drag_obj", если внутри дива есть ещё элементы - ну и как я говорил, совсем для понтов, можно сделать, чтобы всё это можно было вначале мышкой веделять, а потом выделение передвигать Добавлено @ 23:08
|
| Автор: Innuendo 13.2.2006, 23:29 |
| круто! теперь даже при скоростном движение они успевают. А как ты сделал в мозилле, чтоб не выделялось? в общем классно |
| Автор: 12345c 14.2.2006, 04:00 | ||||||
| Да, загадка - мой код срывает перемещение в ie, а твой нет. Всматривался, менял - ничего не помогает. Подменил генерацию кодом - то же самое. Наконец, увидел - у тебя же не берёт функция при onmousemove значение obj.style.left - доступа в DOM лишний раз не идёт, а он у меня рушит "удержание" объекта под мышью, получается. (В ie-opera). И не только, проблемы решились после невыбора каждый раз в onmousemove объекта event.srcElement. Ну и ну. Не зря потраченный вечер. Alx, Придётся и тебе "+" выдать - за плодотворную совместную работу и отвагу на пожаре. Кстати, у тебя маленькая ошибочка - надо zMax=1; , а не 0, иначе первый drag не срабатывает как следует. Мой вариант кода (не люблю тавтологий и бессмыслиц типа "window."):
-
|
| Автор: Alx 19.2.2006, 00:48 |
| ну блин, пока руки не доходят, вот что пока сделал: http://soft.flyweb.in/small/JsDragObjs/example.html Добавлено @ 00:51 только в Файрфоксе почему-то возникает событие ondrag, не знаю как его заблочить... |