css, html, php, javascript, jQuery, ajax … – решения, примеры, рецепты
18 Янв
Внимание! Эта статья устарела. Новая статья по этой теме: «jQuery UI – плагин Draggable«. Давайте продолжим знакомство с элементами пользовательских интерфейсов, которые можно создавать на базе библиотеки jQuery. Попробуем создавать элементы, которые можно будет свободно перемещать по странице с помощью мыши. Вы наверняка уже встречали такие «фичи». Оказывается, с помощью jQuery сделать это самому не составляет почти никакого труда!
Опять же обратимся к сайту разработчиков библиотеки. Там приведен вот такой простой код:
$(".block").draggable();
И это почти все! В этом коде сообщается, что перемещаемыми элементами становятся все элементы с классом block. Но опять же, разработчики предлагают большой набор различных опций, с помощью которых можно извлекать какую-либо практическую пользу. Иначе зачем таскать блоки по странице? Только лишь с целью поразить пользователя? Нет конечно.
Давайте сначала посмотрим пример того, как это работает, а затем мы разберем код, который обеспечивает эту возможность. В примере задана опция возврата элемента на исходную позицию после окончания его перемещения.
Вы можете сохранить исходный код примера и при наличии у Вас библиотеки jQuery, воспроизвести его на своем сайте.
Для того, чтобы элементы действительно стали перемещаемыми, нам потребуется подключить к нашей странице, в разделе HEAD четыре файла:
<script src="js/jquery-1.2.1.js" type="text/javascript"></script> <script src="js/ui.mouse.js" type="text/javascript"></script> <script src="js/ui.draggable.js" type="text/javascript"></script> <script src="js/ui.draggable.ext.js" type="text/javascript"></script>
Первым подключается библиотека jQuery, а затем – файл, выполняющий обработку событий мышки. Два следующих файла работают непосредственно над перемещением элементов по странице.
Далее в этом же разделе HEAD следует таблица стилей в которой мы определим класс (это может быть например и идентификатор) для элементов, которые хотим сделать свободно перемещаемыми.
И наконец код… Естественно, в примере используются не все возможные опции, но я думаю, что сами принципы пример может продемонстрировать неплохо.
$(document).ready(function(){
$(".block").draggable({
revert: true,
drag: function(e,ui) {
$(this).css("background-color","#E2F2E2");
$("#position").text("Положение перемещаемого
элемента - слева: " + ui.position.left + "px,
а сверху: " + ui.position.top + "px");
},
stop: function(e,ui) {
$(this).css("background-color", "#58AEFC");
}
});
});
Весь код «обернут» уже немного знакомой нам
$(document).ready(function(){
...
});
которая отслеживает момент готовности объектной модели документа (DOM).
Это чем-то похоже на событие onload, но в отличие от него разрешает выполнение javascript сразу после того, как DOM готова к работе, а не после полной загрузки страницы.
Итак, вначале мы сообщаем, что перемещаемыми элементами будут все элементы с классом block. А затем просто перечисляем те опции, которые мы хотим использовать.
revert: true указывает на то, что после окончания процесса перетаскивания, элемент должен вернуться на прежнее место.
Опция drag содержит функцию, которая будет выполняться во время самого процесса перетаскивания элемента. В этой функции мы сначала задаем свойство background-color для перетаскиваемого элемента (по-русски – меняем его цвет), а затем в элемент с идентификатором #position вставляем строку текста, в которой сообщаем текущее пололжение левого верхнего угла перетаскиваемого элемента относительно окна браузера.
В опции stop мы определяем функцию, которая выполнится в момент остановки процесса перемещения элемента и просто вернет цвет элемента к начальному.
Вот и все. Далее я привожу всего несколько опций. Полный их перечень можно найти на сайте разработчиков библиотеки jQuery.
axis – ограничивает перемещение по горизонтальной (x) или вертикальной (y) осям.
containment – ограничивает перемещение к в пределах границ указанного элемента – может быть элемент DOM, родительский элемент, документ или селектор jQuery.
effect – эффекты от начала перемещения до остановки. Возможно например FadeIn при старте и FadeOut при остановке.
opacity – прозрачность перемещаемого элемента.
revert – если истина, элемент вернется на позицию откуда было начато перемещение.
start(e,ui), drag(e,ui) и stop(e,ui) – функции, которые могут вызываться при начале, окончании или процессе перетаскивания элементов.
Отзывов (36) на «Пользовательские интерфейсы jQuery: свободно перемещаемый контент.»
Статья отличная, спасибо!!!
а как сохранить положение в БД, чтоб при загрузке в следующий раз пользователь видел этот элемент на том же месте, куда его сам переместил?
Знаете, если совсем честно, то я пишу только о том, что испытал сам, «через руки» так сказать. Может удивительно, но мне пока задачи сохранить положение блока не встретилось. Правда, я думаю, что решать ее стоит не сохранением в БД, а наверное логичнее использовать cookie.
Если удастся, постараюсь в ближайшее время дать такую статью.
Спасибо за ответ.
Только я не понял, где брать файлы, подключаемые, помимо библиотеки самой?
Пожалуйста http://dev.jquery.com/view/tags/ui/1.5b/
Спасибо огромное!!!
Мегареспект!
блин, у меня не работает Ваш пример
покажите, плз, где у меня руки кривые?
файлы есть вроде все… лежат в корне в папке «js» как и в примере
собственно, все остальные также(((
Попробуйте взять нужные файлы отсюда http://www.linkexchanger.su/download
На сайте разработчиков не всегда выложены версии файлов с пофиксенными багами, приходится искать нормальные, рабочие версии. В разделе download все те файлы, которые используются в примерах.
Отличная статья, красивый код и море удовольствия от работы. Все быстро и успешно настроилось.
Так держать, Gennady, и спасибо за полезный и качественный ресурс!
To: Алексей
Вы спрашивали как сохранить положение блоков на странице, а я обещал написать об этом. Написал, смотрите тут: http://www.linkexchanger.su/2008/42.html
Здравствуйте.
У меня есть вопрос, возможно не совсем в тему.
Создал на страничке некий draggable DIV, после чего сделал его еще и resizable, но вот в чем проблема: он перестал таскаться, но может менять размер. Если убрать resizable, то все прекрасно драгается
Не подскажете в чем может быть проблема?
С уважением, Сергей.
Посмотрите эту http://www.linkexchanger.su/2008/32.html статью. Может она решит Вашу проблему. C resizable очень близко не знакомился – не было особой нужды. Кстати, в одном из примеров на сайте разработчиков resizable тоже не работает. Но, вообще мне кажется, что он зависит не только от ui.mouse.js, но и от jquery.dimensions.js
Если последний у Вас не подключен – попробуйте его подключить.
Спасибо большое за ответ.
Статья мне не поможет, так как DIV мой должен послужить, увы, не диалоговым окном или контейнером сообщения.
Что не работает у них – заметил, сам удивлён, хотя глядел сорцы, все прописано и сделано, странно в общем.
Что странно ещё: скачал сегодня последнюю версию UI, но там уже нет файла ui.mouse.js, видимо интегрировали в какой-то другой модуль.
А вот где взять jquery.dimensions.js, не совсем ясно. Можете уточнить?
Заранее благодарю.
Файл jquery.dimensions.js нашёл… не помогло
В одной англоязычной статье прочитал, что уже возникали подобные проблемы раньше у народа.
Ответы были банальными – сменить версию ui на более свежую.
Кстати, новая версия jquery.ui-1.5rc1, решила мою проблему
Обновляйтесь господа!
Генадий, у меня такой вопрос. Есть задача по окончанию перемещения элемента изменить его draggable-свойства. Застрял на этапе их получения. Пример:
$(‘#insideParent’).Draggable({
zIndex: 1000,
opacity: 0.7,
……
onStop: function() {
/*Как написано здесь – http://docs.jquery.com/UI/Draggable, свойство можно получить например так*/
var grid = $(this).draggable(‘option’, ‘grid’);
}
});
Вот при получении свойства и возникает ошибка : Type mismatch (usually non-object value supplied where object required) Не подскажете, где я ошибаюсь?
Вероятно потому, что вызывая callback-функцию в onStop, Вы используете this, которая в этом контексте не определена. Попробуйте сначала сохранить ссылку на элемент, который Вы хотите сделать перемещаемым:
var el = $(‘#insideParent’);
затем уже делать:
el.draggable({ … });
где в опции onStop укажете:
function(){
var grid = el.draggable(‘option’,'grid’);
}
Спасибо, вроде разобрался, но следом ещё один вопросик:)
При присвоении нового draggable-свойства, все текущие свойства эл-та слетают, например, я добавляю $(‘#insideParent’).draggable({axis:’x'});
после чего все остальные опции эл-та перестают работать. Приходится кроме добавленного обьявлять все заново, некрасиво как-то:) Т.е вместо получения обьекта (или ссылки на обьект) и добавления ему новых свойств я по сути обьявляю новый обьект. Возможно это сделать более красиво?
Своей цели я достиг, это просто любопытство, спасибо ещё раз.
В принципе рецепт тот же самый. Почему у Вас «слетают» все свойства – потому, что Вы создаете новый набор и ставите ему только одно свойство.
Генадий, помогите, не могу считать свойства ui.position.left и ui.position.top. Вот код :
$(«.block»).draggable({
drag: function(e,ui) {
$(«#position»).text(«Положение перемещаемого элемента – слева: » + ui.position.left + «px, а сверху: » + ui.position.top + «px»);
}
});
Вот сам див:
xxxxxxxxxx
При драг и дропе текст дива не меняется
Ну чем же помочь-то? Ведь рабочий пример есть у Вас…
Смотрите – перемещаемый элемент должен иметь класс block (иначе он и не будет перемещаемым). В опции drag определена простая callback-функция, которая обращается к свойствам left и top объекта position (он в свою очередь является свойством объекта ui) и вставляет значения (вместе с сопутствующим текстом) в элемент с id=»position». Вроде все просто…
Да как бы да, но работать не хочет…Где можно прочитать про объект ui ? Что это ?
Почитать можно тут:
http://docs.jquery.com/UI/Draggable
Кстати, если открыть в отдельном окне ваш пример по ссылке «исходный код», то он у вас тоже не работает
По ссылке «исходный код» хранится html-файл примера и только лишь… Для того, чтобы он заработал, к нему необходимо подключить все требуемые файлы, как это сделано при демонстрации примера во фрейме. А сделано это для того, чтобы заставлять включить мозг и разбираться, а не делать банальный копипаст
Блин, похоже тупо версии библиотек не совпадают.
Кстати в примере исходного кода вроде библиотеки подключены. Вот кусок оттуда :
Подключены конечно. Только в состав архива они не входят и их надо скачивать отдельно…
Да неее…Похоже, я вам не стой стороны объясняю. Если извлечь вашь пример и подключить к нему библиотеки, то драг и дроп работает, но див, который должен показывать координаты во время перетаскивания, ничего не показывает. Правда я библиотеку подключаю не 1.2.1 а 1.3.2
Блин, подключил к своему сайту библиотеку скачанную у вас, более старую – всё заработало. Пол дня ковырялся с этим.
Геннадий, подскажите пожалуйста, как нужно дополнить код, чтобы при перемещении голубого квадрата(draggable) в зону красного квадрата(droppable) он автоматом примыкал к краям, т.е вмещался один в один. Спасибо.
В опциях Draggable такого нет. Регулировать можно только величину области перекрытия draggable-блока и droppable – целевого элемента, в момент «сброса». Это опцией tolerance можно задать. А так, чтобы сбрасываемый элемент автоматом выравнивался под целевой – такого нет.
Вообще лучше смотреть свежую информацию тут:
http://jqueryui.com/demos/
Пробовал все из значений tolerance… не примыкает, так же пробовал у целевого элемента прописывать float: left . возможно можно задать чтобы сбрасываемый элемент сразу прилегал к верхнему левому краю?
Я объяснял… Опция tolerance это несколько не то, что Вам надо. Штатных методов у плагина для решения Вашей задачи нет. Надо думать самому. Примерно в таком направлении:
- можно использовать опцию drop, определив в ней callback-функцию, которая будет выполняться в момент «сброса»;
- в этой функции сначала определить положение целевого элемента – его координаты относительно левого верхнего угла с помощью метода offset() например;
- и наконец использовать объект ui.helper для установки нужных значений хотя бы через его css-свойства. Что-то вроде ui.helper.css(«left», 20);
а как узнать id перемещаемого элемента ?
Ну, во-первых, я бы все-таки рекомендовал читать не эту старую статью, а jQuery UI – плагин Draggable…
А получить значение id (или любого другого атрибута) перемещаемого элемента довольно просто. Надо воспользоваться каким-либо из событий на которые может реагировать плагин – например, событие stop (окончание перемещения элемента). В callback-функции, которая срабатывает при наступлении события можно обратиться к элементу, который только что окончил перемещение, через this.
Вот так: var id = $(this).attr(«id»);
А вообще технические вопросы лучше задавать на форуме jQuery.
Оставьте отзыв