css, html, php, javascript, jQuery, ajax … – решения, примеры, рецепты
5 Окт
Плагин Draggable – один из нескольких плагинов, входящих в состав jQuery UI, с помощью которых можно организовать взаимодействие с элементами веб-станиц. Плагин Draggable позволяет делать выбранные элементы веб-страницы перемещаемыми с помощью указателя мыши. Наведите указатель мыши на зеленый квадрат, нажмите левую клавишу мыши и попробуйте перемещать его.
А теперь посмотрите, насколько легко это реализовать….
Для начала посетим страницу настраиваемой закачки на сайте jQuery UI, чтобы получить необходимые нам файлы. Щелкаем на ссылке Deselect all component, чтобы не закачивать лишнее, а затем выбираем только то, что нам потребуется – отмечаем чекбокс Draggable и видим, что вместе с ним отметился чекбокс UI Core. Работа плагина Draggable зависит от него, поэтому он необходим.
Кроме этого, справа есть выпадающий список, где можно выбрать понравившуюся тему оформления. Если все готово, кликаем кнопку Download и получаем архив.
Сначала в разделе HEAD подключаем несколько файлов, которые есть в архиве.
<link type="text/css" href="css/le-frog/jquery-ui-1.7.2.custom.css" rel="stylesheet" /> <script src="js/jquery-1.3.2.min.js" type="text/javascript"></script> <script src="js/jquery-ui-1.7.2.custom.min.js" type="text/javascript"></script>
Итак, сначала мы подключили файл стилей css/le-frog/jquery-ui-1.7.2.custom.css одной из многочисленных тем оформления. Кроме этого мы подключили файл библиотеки – js/jquery-1.3.2.min.js и файл js/jquery-ui-1.7.2.custom.min.js, в котором объединена функциональность ядра UI и плагина Draggable (на самом деле для использования в примерах этой статьи там содержится еще и функциональность плагинов Droppable и Sortable).
Смотрим HTML-разметку. Пусть у нас она будет выглядеть так:
<div id="draggable" class="ui-widget-content"> <p>Drag me</p> </div>
Связываем функциональность плагина Draggable с выбранным элементом:
$(function(){
$("#draggable").draggable();
});
Пока мы использовали плагин Draggable с настройками по умолчанию. Но он может принимать более 20 различных опций, которые помогают очень гибко настроить его под конкретные условия использования.
Попробуем передать плагину несколько настроек:
$(function(){
$("#draggable").draggable({
cursor: "move",
revert: true,
revertDuration: 3000
});
});
Здесь мы изменили вид курсора во время перемещения элемента, и добились того, что по окончании перемещения элемент самостоятельно вернется в свое начальное положение в течение 3 секунд.
Остальные опции используются аналогичным образом, самое главное – знать их название и понимать какая за что отвечает.
addClasses – по умолчанию эта опция имеет значение true. Если установить значение false, то это предотвратит добавление класса ui-draggable к перемещаемым элементам. Это может потребоваться из соображений оптимизации при вызове .draggable() например, для нескольких сотен элементов.
appendTo – по умолчанию эта опция имеет значение ‘parent’. В ней можно передать селектор jQuery или элемент, который будет использован в качестве контейнера для объекта, представляющего перемещаемый элемент во все время его перемещения.
axis – вынуждает перетаскиваемый элемент перемещаться только по оси x или только по оси y. Значение по умолчанию false, что позволяет элементу перемещаться свободно.
cancel – по умолчанию эта опция имеет значение ‘input, option’. Если эти элементы находятся внутри перемещаемого элемента, то перемещаемый элемент нельзя захватить, при нахождении указателя мыши над определенными в этой опции элементами. Для выбора элементов используется селектор jQuery.
connectToSortable – разрешает «сброс» перемещаемых элементов в сортируемый (sortable) список. При этом «сброшенный» элемент становится частью списка. В качестве значения указывается селектор jQuery. По умолчанию имеет значение false. Для корректной работы необходимо дополнительно использовать опцию helper со значением ‘clone’.
containment – ограничивает перемещение внутри определенного элемента или области. В качестве значения может принимать селектор jQuery, элемент, строку или массив. Примеры возможных значений: ‘parent’, ‘document’, ‘window’, [x1, y1, x2, y2].
cursor – строка, в которой может быть передано css значение, определяющее значок для курсора в процессе перетаскивания элемента. По умолчанию – auto.
cursorAt – при перемещении элемента устанавливает курсор в определенную позицию. Например, значение {left: 5, top: 10}, при перемещении установит курсор в 10 пикселах от верхнего края и 5 пикселах от левого края.
delay – отсрочка начала времени перемещения элемента в миллисекундах. Опция используется для того, чтобы предотвратить нежелательное перемещение элемента во время случайного щелчка по нему. По умолчанию имеет значение 0.
distance – расстояние в пикселах, на которое должен переместиться курсор при удерживаемой в нажатом положении левой клавиши мыши прежде, чем начнется перемещение элемента. Опция используется для того, чтобы предотвратить нежелательное перемещение элемента во время случайного щелчка по нему. По умолчанию имеет значение 1.
grid – заставляет перетаскиваемый элемент перемещаться дискретно, по сетке, определяемой массивом передаваемых в опцию значений. Значение по умолчанию false, что позволяет элементу перемещаться свободно. Пример передаваемого значения – [10, 10].
handle – в этой опции можно определить элемент, находящийся внутри перемещаемого элемента, при нахождении над которым указателя мыши будет возможен захват перемещаемого элемента. Для выбора элементов можно использовать селектор jQuery.
helper – возможные значения опции – ‘original’, ‘clone’, Function. По умолчанию установлено значение ‘original’ – визуально наблюдается перемещении самого элемента. При использовании значения ‘clone’ перемещаться будет клон элемента, а сам элемент при этом остается на своей позиции. В опции можно определить функцию. Функция обязательно должна возвращать DOM элемент.
iframeFix – по умолчанию установлено значение false. Если установить значение true, будет предотвращен перехват события mousemove во время перемещения элемента при прохождении указателя мыши над iframe. В качестве значения может быть использован селектор jQuery – при этом предотвращение перехвата будет производиться только при прохождении указателя мыши над выбранными iframe. Опция бывает полезна при использовании совместно например с cursorAt.
opacity – устанавливает значение css-свойства opacity для элемента, находящегося в процессе перемещения. По умолчанию установлено значение false, что соответствует полной непрозрачности.
refreshPositions – по умолчанию используется значение false. При значении true позиция «сброса» элемента будет пересчитываться при каждом событии mousemove. Использовать с осторожностью! Такой подход может помочь создать очень динамичное приложение, но безусловно снизит производительность.
revert – значение по умолчанию – false. Если установить значение true, то элемент возвратится на свою исходную позицию после окончания перетаскивания. Также можно передать значения в виде строки. Возможные значения – ‘valid’ или ‘invalid’. Эти значения используются в случае, если перемещаемый элемент будет «сброшен» в какой-либо целевой элемент. При использовании значения ‘valid’ перемещаемый элемент возвратится в предыдущую позицию только в том случае, если был «сброшен» в целевой элемент. При использовании значения ‘invalid’ не возвратится в предыдущую позицию только в том случае, если он был «сброшен» в целевой элемент.
revertDuration – длительность эффекта возвращения элемента на исходную позицию, в миллисекундах. По умолчанию имеет значение 500. Опция игнорируется, если опция revert имеет значение false.
scope – значением этой опции является строка. По умолчанию установлено значение ‘default’. Перемещаемые элементы, имеющие в опции scope точно такое же значение, как и значение опции scope для элементов с функциональность droppable, будут приниматься этими элементами. По сути, дополняет опцию accept плагина Droppable.
scroll – по умолчанию установлено значение true – при перемещении элемента к краю области просмотра, она автоматически прокручивается бесконечно. Если установить значение false, эта возможность будет запрещена.
scrollSensitivity – число, определяющее расстояние в пикселах от края области просмотра, после которого она начинает прокручиваться. Расстояние определяется относительно указателя мыши, а не перемещаемого элемента. По умолчанию установлено значение 20.
scrollSpeed – число, определяющее скорость, с которой прокручивается область просмотра при приближении указателя мыши к ее краю на расстояние определенное в опции scrollSensitivity. По умолчанию установлено значение 20.
snap – по умолчанию установлено значение false. Если установить значение true (что эквивалентно ‘.ui-draggable’, поскольку значение может определяться также селектором jQuery), то перемещаемый элемент будет «прилипать» к краям выбранных элементов при прохождении около них.
snapMode – опция определяет, как именно перемещаемый элемент будет «прилипать» к выбранным элементам. Например, только к внешним или только к внутренним сторонам элементов. Возможные значения ‘inner’, ‘outer’, ‘both’. Любое значение игнорируется при snap: false. По умолчанию установлено значение ‘both’.
snapTolerance – расстояние в пикселах от перемещаемого элемента до выбранного, при котором произойдет «прилипание». По умолчанию установлено значение 20. Любое значение игнорируется при snap: false.
stack – объект, с помощью которого осуществляется автоматический контроль за свойством z-index определенной группы перемещаемых элементов, всегда помещая перемещаемый элемент поверх остальных. Значение свойства ‘group’ определяет jQuery селектор. Дополнительно можно определить свойство ‘min’, число ниже которого значение z-index опуститься не сможет. Например: $(‘.selector’).draggable({ stack: { group: ‘.selector’, min: 50 } });
zIndex – число, определяющее значение свойства z-index перемещаемого элемента. По умолчанию false.
Кроме возможности гибкой настройки плагина Draggable, есть возможность заставить его реагировать на некоторые события. Вот пример:
$(function(){
$("#draggable").draggable({
cursor: "move",
stop: function(event, ui) {
alert("Событие: " + event.type +
"\n\ntop: " + ui.offset.top +
" px\nleft: " + ui.offset.left +
" px");
}
});
});
Мы определили в опции stop callback-функцию. Функция принимает два аргумента – объекты event и ui. На простом примере показано, каким образом можно обратиться к свойствам этих объектов. В итоге, при окончании перемещения элемента, в окне предупреждения мы увидим информацию о типе наступившего события – dragstop, и текущее абсолютное положение элемента на странице.
Опций, связанных с событиями только три:
Опция start – событие dragstart наступает каждый раз при начале перемещения элемента.
Опция drag – событие drag наступает все время, пока элемент находится в процессе перемещения.
Опция stop – событие dragstop наступает каждый раз при завершении перемещения элемента.
Любая callback-функция, определенная в опциях start, drag или stop принимает два аргумента – event и ui. Объект event – это объект события, а объект ui – это специальный объект, в свойствах которого содержится следующая информация:
ui.helper – объект, характеризующий элемент, находящийся в процессе перемещения;
ui.position – объект, в свойствах top и left которого содержится информация о положении перемещаемого элемента относительно родительского элемента;
ui.offset – объект, в свойствах top и left которого содержится информация об абсолютном положении перемещаемого элемента;
Нам осталось познакомиться с методами плагина Draggable. Но для этого нам понадобится добавить в HTML-разметку пару кнопок. Вот так:
<button id="getOption">Get Option</button> <button id="setOption">Set Option</button>
В следующем примере продемонстрировано как получать и устанавливать значения опций плагина после его инициализации:
$(function(){
$("#draggable").draggable({
cursor: "move"
});
$("#getOption").click(function(){
alert($("#draggable").draggable("option","grid"));
});
$("#setOption").click(function(){
$("#draggable").draggable("option","grid",[50,50]);
});
});
Мы связали с кнопками Get Option и Set Option событие click. При щелчке на кнопке Get Option мы вызовем метод option, название которого указываем в первом аргументе, а во втором аргументе передаем название опции, значение которой мы хотели бы получить. В итоге мы увидим окно предупреждения, в котором будет показано значение false, поскольку при инициализации эта опция не была определена, а по умолчанию она имеет именно такое значение.
Попробуйте перетаскивать элемент с помощью мыши – он будет плавно перемещаться в любых направлениях.
Сделаем щелчок на кнопке Set Option, снова вызывая метод option, но теперь мы передаем три аргумента. Первый – название метода, второй – название опции, значение которой мы хотим изменить, и третий аргумент – новое значение опции. Таким образом, передав опции grid значение [50,50] мы заставим элемент перемещаться дискретно, вдоль сетки с шагом 50х50 пикселей.
Доступные методы плагина Draggable:
destroy – .draggable(‘destroy’) полностью удаляет всю функциональность плагина Draggable. Возвращает элементы в состояние, предшествующее инициализации.
disable – .draggable(‘disable’) временно запрещает использование всей функциональности плагина. Вновь разрешить ее использование можно с помощью метода enable.
enable – .draggable(‘enable’) разрешает использование всей функциональности плагина, если ранее она была запрещена с использованием метода disable.
option – .draggable(‘option’, optionName, [value]) с помощью этого метода можно получить или установить значение любой опции плагина после инициализации.
Все примеры, использованные в статье, можно совершенно запросто получить в этом архиве.
Для тех, кто смог все это прочитать до конца (а также для тех, кто сразу прокрутил страницу вниз) сообщаю, что в архиве Вы найдете и еще один пример, где показано как можно реализовать перемещение и «сброс» элемента несортируемого списка в другой, сортируемый список.
Отзывов (19) на «jQuery UI – плагин Draggable»
СПАСИБО!!! Отличная статья!
много тебе еще осталось переводить? не думал отдельный сайтег с маном сделать?
Мануалы на русском есть. Вот например:
http://slyweb.ru/jquerymain/
А у меня на блоге несколько другая форма подачи. Тот же манул, но поданный по возможности на человеческом языке, с примерами, которые помогают понять суть и все возможности плагина (если это UI например) или возможности самой библиотеки.
Если указать параметр SNAP, то перемещаемый элемент будет «прилипать» к краям выбранных элементов при прохождении около них.
Как узнать к каким конкретно элементам он прилип?
Не узнать наверное, а назначить элементы к которым он «прилипает».
Опции snap, snapMode и snapTolerance обычно вместе используются, примерно так:
snap: «body»,
snapMode: «inner»,
snapTolerance: 50
т.е. как только перемещаемый элемент приблизится на расстояние 50px к границе body изнутри, он как бы «прыгнет» и «прилипнет» к body.
Если же указать в опции snap просто true, то прилипать перемещаемый элемент должен ко всем элементам у которых есть класс .ui-draggable.
Вот про «ко всем элементам у которых есть класс .ui-draggable» как раз и вопрос. Есть 10 таких элементов, у каждого свой id. Наш div «прилип» к двух из этого списка. Надо узнать их id.
И еще один вопрос возник: как проверить на «наложение» нашего div на указанные в snap? Что бы запретить пересечение – только прилипание по краям.
Для того чтобы реализовать и первое и второе, без дополнительных «телодвижений» не обойтись, поскольку плагин такой функционал не предоставляет.
Как именно это делать – вопрос другой. Ну например в первом случае можно попробовать задействовать опцию stop, но что делать дальше не очень понятно…
В общем все зависит от того что именно Вы пытаетесь сделать (в общем смысле конечно).
Спасибо за отличную статью!
Столкнулся с проблемой, что если таскать див1 внутри див2, причем див1 большей размерности чем див2, то перемещение идет рывками, по углам. Можно это как-то вылечить, чтобы было плавное перемещение?
Код:
#draggable { width: 600px; height: 600px; }
#area { width: 200px; height: 200px; overflow: hidden; }
$(function(){
$(«#draggable»).draggable({
cursor: «move»,
containment: «#area»
});
});
…
У Вас containment: «#area» лишнее… Почему? Попробуйте сначала дать диву #draggable размеры, скажем 190×190 и сразу станет ясно, почему внутренний див двигается скачками…
Геннадий, там у меня затык оказался не только в этом
В конечном счете решил проблему через задание contaiment массивом координат. Единственное в таком варианте обязательное условие: при ресайзе страницы надо через .draggable(‘option’, optionName, [value]) устанавливать новые координаты.
А в общем уже все работает и проблема решена. И еще раз спасибо вам за отличный блог и статьи!
Хотя да… Сейчас попробовал ваш совет, что containment стоит вообще убрать и все заработало ничуть не хуже моего решения, но у вас оно значительно проще
Таки при детальных тестах ваш вариант работает неверно под мою задачу
То есть, таскает как угодно попало, а надо чтобы за границы не выходил.
В общем – конечно. Если надо таскать в маленьком диве большой, не выползая при этом за рамки (например большая карта в маленьком экране), то надо задавать через containment вычисляемые через offset координаты базы, после чего сразу менять настройки draggable. Плюс к этому надо на resize повесить пересчетчик данных. В этом варианте таскание будет всегда верным, как бы вы окна ни кривили и ни дергали
Подскажите, пожалуйста, как сделать что бы
$(«#dragssss»).draggable({ containment: ‘window’ });
не глючил в случае если размеры блока dragssss больше чем размер экрана?
ссори за оффтоп, у меня такая же проблема как и у FM….
FM, можете поделится решением?
как убрать эффект dragable с элемента ? то етсь по надатию кнокпи чтобы нельзя было больше его таксать?
ну или изменть свойства dragable.
напрмиер было
draggable({ containment: ‘parent’});
а нужно по нажатию кнопки добавить
draggable({ containment: ‘parent’, snap:true});
Доступные методы плагина Draggable:
destroy – .draggable(‘destroy’) полностью удаляет всю функциональность плагина Draggable. Возвращает элементы в состояние, предшествующее инициализации.
disable – .draggable(‘disable’) временно запрещает использование всей функциональности плагина. Вновь разрешить ее использование можно с помощью метода enable.
enable – .draggable(‘enable’) разрешает использование всей функциональности плагина, если ранее она была запрещена с использованием метода disable.
option – .draggable(‘option’, optionName, [value]) с помощью этого метода можно получить или установить значение любой опции плагина после инициализации.
Валерий, Вы задали вопрос, сами же себе и ответили… Или осталось что-то непонятное? Тогда обратитесь к примерам в статье – там демонстрируется как получать и устанавливать значения для выбранной опции после инициализации. А destroy(‘destroy’) – в общем по тому же принципу.
Валерий, правильное таскание через задание window в containment не получится (у меня не вышло для всех браузеров). Но получится через явное задание координатной области. В случае смещения и/или изменения размера окна, где надо таскать, нужна переустановка данных через option.
Минус такого подхода один, но серьезный. Надо внимательно считать координаты области, внутри которой таскаем. Если вложенных дивов много, то могут быть косячки… И особое внимание на Оперу, а именно – на абсолютность координат, с относительными там draggable работает много где криво
Обсуждение статьи можно продолжить на форуме jQuery.