Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > JavaScript: Общие вопросы > Drag & Drop не могу разобраться |
Автор: GF 17.11.2006, 16:04 | ||
Никогда не нужно было решать задачи с Драг энд Дропом, а тут вдруг пришлось. Не могу сделать примитивнейшую прогу- чтоб можно было перетаскивать картинку по горизонтали. Вот код:
В таком некрасиво-чудовищном виде она работает в Opera и IE, но болеет в FF ![]() Кто может исправить код так, чтоб она нормально работала везде? Ещё хотелось бы, чтоб в IE и FF при перетаскивании курсор имел бы тот же вид. Может кто предложит более красивый вариант без такого количества обработчиков событий??? |
Автор: 12345c 17.11.2006, 16:59 |
Нет, с количеством событий всё правильно. ![]() |
Автор: AKS 17.11.2006, 20:34 | ||
GF,
|
Автор: SelenIT 18.11.2006, 01:53 |
12345c, можно задать несколько вопросов по Вашему примеру по ссылке? 1. Обязательна ли проверка navigator.appName? Я попробовал заменить во всех условиях "FF" на "e" - работает (IE6, FF2, Opera 8-9), да и имхо логичнее пускать Оперу по W3C-шной ветке, чем по IE-шной... Где я упустил что-то важное? 2. Верно ли я понимаю, что ondragstart актуален только для IE и только в том случае, когда перетягиваемыми объектами являются ссылки, а для обычных элементов (тех же div-ов) его можно смело опускать? 3. onselectstart, по-видимому, тоже работает только в IE - так ли это? Для Мозиллы и Сафари, насколько мне известно, того же эффекта можно добиться из CSS: (-moz-,-khtml-)user-select: none (аналога для Оперы я, к сожалению, не нашел)... Кстати, при экспериментах с перетягиваением ссылок в FF2 обнаружилась небольшая странность с этими стилями - с ними перетягивание ссылок не работает (симптомы - курсор в виде запрещающего знака, mousemove начинает работать только после отпускания кнопки - похоже, что mouseup игнорируется). Без этих стилей и ссылки нормально перетягиваются. А в IE примерно то же наблюдается со ссылками, если убрать ondragstart (с дивами этого не происходит - на них ondragstart не влияет...). Те же симптомы наблюдались у меня в примере GF после того, как объект "перескакивал" в момент захвата к -50px от курсора. Интересно, что за событие происходит в FF в момент первого движения курсора по объекту или объекта под курсором, которое приводит к таким артефактам, но не ловится обработчиками? |
Автор: AKS 18.11.2006, 11:28 | ||
SelenIT,
Попробуйте добавить в обработчики mousedown/mousemove вот это: e.preventDefault()... |
Автор: SelenIT 18.11.2006, 14:24 |
AKS, спасибо, с preventDefault() в onmousedown в FF ссылки стали тягаться и при запрете выделения через CSS. В IE тоже хватило "заглушить" с помощью returnValue=!1 однин обработчик, но уже как раз onmousemove ![]() Так что же, делаем вывод - ondragstart и т.п. вообще "не при делах"? |
Автор: SelenIT 18.11.2006, 15:56 | ||
12345c, спасибо за ответы! А вот результат моих изменений того же скрипта:
Если "закомментарить" строчки 35 или 41, в каком-то браузере начинаются проблемы со ссылками, но с дивами по-прежнему все ОК. P.S. Виноват, не дочитал добавление. Все-таки насчет ondragstart-а: у меня получилось, что аналогичный эффект в IE дает event.returnValue=!1 в onmousemove (как предложил AKS). В чем подводные камни? |
Автор: 12345c 18.11.2006, 16:20 | ||
![]() |
Автор: SelenIT 19.11.2006, 06:15 | ||||
12345c, а почему все-таки нельзя заменить везде if(FF) на if(e) и вообще избавиться от определения браузера в каком-либо виде? Кроме того, у меня сложилось мнение, что returnValue=!1; в mousemove отменяет в IE и drag, и select. Если так, то, по-моему, одна доп. строчка в onmousemove явно выглядит "аккуратнее" целых двух некроссбраузерных доп. обработчиков (тем более, что e.preventDefault(); из mousedown-а все равно ведь выкинуть нельзя) - даже по "количеству букв" вариант с ней короче. Да и концептуально мне оно кажется вернее - поскольку фактически drag'n'drop формируется тремя событиями, то и скрипт ограничивается тремя обработчиками, доведенными "до абсолюта"... А проблема GF, с учетом полученных в топике знаний, похоже решается вообще просто:
вдогонку... 12345c, кстати, код GF натолкнул меня на мысль, как можно еще чуточку компактизировать работу с координатами, в итоге все обработчики из первоначального варианта (без Ваших новых правок с проверкой сдвига курсора на ссылке и т.п.) сократились до следующего вида:
Полагаю, потеря совместимости с NN4 - не такая уж большая беда... |
Автор: SelenIT 19.11.2006, 23:33 | ||
Осмелюсь предложить еще одну вариацию на тему, имхо так читается немного легче:
Код обработчиков немного упростился за счет выноса дублирования во вспомогательные функции. Кстати, если это переделать на объектный лад и навешивать обработчики через attachEvent/addEventListener (следующий этап оптимизации;), можно по этому же attachEvent/addEventListener сделать проверку при объявлении этих функций, и вообще избавиться от следов браузерных проверок в рантайме (уже делаю;). А вот с кликами обнаружилась неприятная (хоть и не критичная) вещь в Опере 8 - там onclick после сдвига курсора и сам не происходит, поэтому блокировка не сбрасывается и первый клик после отпускания тягаемой ссылки "по инерции" блокируется, срабатывает только второй. К счастью, в 9-й Опере все нормально, а 8-я стремительно теряет актуальность... |
Автор: 12345c 19.11.2006, 23:56 |
Да, в 7.54 так же со ссылками (насколько проще без них было ![]() Код смотрится действительно лучше. Когда возьмусь доделывать Оперу, учту ![]() Оперы довольно крепко сидят у юзеров, в отличие от FF, по статистике посещений. Поэтому год-два их надо поддерживать. Оперы-7, например, имеют 0.5% от общего кол-ва, а все Оперы вместе - порядка 11%, а 8-я - около 3%. Это довольно много для старых версий. Ещё полгода назад с 6-й ходили. |
Автор: SelenIT 20.11.2006, 00:26 | ||
Все же я считаю проблему старых Опер некритичной, тут же не полная потеря функциональности, а лишь мелкое неудобство (подумаешь, лишний клик). И переход с 8-й на 9-ю, по моим наблюдениям за http://gs.spylog.ru/r/?dayFrom=1&monthFrom=1&yearFrom=2006&dayFor=20&monthFor=11&yearFor=2006<Type=3&radioReportOption=visitors&browser_name=Opera&browser_version=__top__&x=19&y=19&graphCurve0=Microsoft%2BInternet%2BExplorer%2B6&graphCurve1=FireFox%2B1&graphCurve2=Microsoft%2BInternet%2BExplorer%2B5&graphCurve3=Opera%2B8&graphCurve4=Opera%2B9&graphCurve5=Opera%2B7&graphCurve9=FireFox%2B2&graphCurvebrowser_name=__all__&graphCurvebrowser_version=__top__&ableSubmit=0&graphCurveNumbers=33&graphCurveCheckedNumbers=7&curvePerGraph=7&order=visitors&desc=1&inner=0&reportId=10&categoryId=1&representationType=graph, идет гораздо быстрее чем было между прошлыми версиями (как-никак системные требования те же, а возможности лучше в разы, причем все это бесплатно)... ...хотя что-то я притупил, по сути ведь вся доработка сведется к замене wasDrag=1 в onmousemove на что-то вроде
|
Автор: GF 20.11.2006, 14:09 |
Всё, разобрался. За основу взял скрипт, предложенный SelenIT, выкинув из него ненужные мне вещи. всем спасибо за помощь! |