Внимание! Эта статья устарела. Новая статья по этой теме: «jQuery UI – плагин Droppable«. Библиотека jQuery предоставляет возможность не только легко и просто написать код, который позволит свободно перемещать элементы по странице. В ее состав, вернее в состав ее расширений входит функция droppable, которая позволяет также довольно просто написать код, который будет обрабатывать события, которые происходят в момент окончания перемещения элемента.
Что полезного с практической точки зрения можно сделать, воспользовавшись такой возможностью. Первое, что приходит в голову – это какая-нибудь интерактивная корзина для интернет-магазина. Вот и попробуем сделать такой пример.

Как всегда сначала попробуем испытать готовый пример, а затем разберемся как работает этот код. Берем мышкой нужный продукт и тащим его в корзину. Над корзиной отпускаем и смотрим, что получилось…

Чтобы не усложнять код примера, не применяются некоторые проверки, которые должны быть использованы в целях безопасности в реальных интернет-магазинах.

Вы можете сохранить исходный код примера и при наличии у Вас библиотеки jQuery, воспроизвести его на своем сайте.

Чтобы все это работало, нам потребуется подключить к нашей странице, в разделе HEAD довольно много файлов (за исключением самой библиотеки эти файлы не очень большие):

<script type="text/javascript" src="js/jquery-1.2.1.js"></script>
<script type="text/javascript" src="js/jquery.dimensions.js"></script>
<script type="text/javascript" src="js/ui.mouse.js"></script>
<script type="text/javascript" src="js/ui.draggable.js"></script>
<script type="text/javascript" src="js/ui.draggable.ext.js"></script>
<script type="text/javascript" src="js/ui.droppable.js"></script>
<script type="text/javascript" src="js/ui.droppable.ext.js"></script>

Большинство их уже знакомы по предыдущим примерам, добавились только ui.droppable.js и ui.droppable.ext.js, которые и обеспечат нам те возможности, которые мы собираемся рассмотреть.

Не будем очень уж внимательно рассматривать таблицу стилей, поскольку здесь в основном это дело вкуса. Остановлюсь только на ее отдельных моментах.

.products {
  float:left;
}
#basket {
  background-color:#e9b96e;
  border:3px double #c17d11;
  width:150px;
  height:120px;
  margin:10px;
  padding:3px;
  position:absolute;
  top:5px;
  right:5px;
}

В работе примера используются элементы с классом .products и идентификатором #basket (понятно, что products – это товары интернет-магазина, а basket – корзина). Никаких подводных камней тут нет, можно использовать любой стиль отображения этих элементов. Единственное, что необходимо учитывать – наш скрипт будет обращаться к этим элементам по имени класса и идентификатора.
Можно упомянуть еще два класса из таблицы стилей:

.droppable-active {
	outline:1px dotted #F00;
}
.droppable-hover {
	outline:1px dotted #00F;
}

Класс .droppable-active будет использован скриптом в тот момент, когда процесс перемещения элемента уже начался, но перемещаемый элемент еще не находится «в зоне действия» целевого элемента. А класс .droppable-hover будет применен, когда перемещаемый элемент окажется над целевым.

Сам HTML-код вообще не представляет собой ничего особенного: несколько картинок, целевой блок, блок вывода результатов. Все это Вы сможете посмотреть, если скачаете файл примера. А вот сам JavaScript, который все это обрабатывает, разберем подробнее. Код получился немножко длинноват, но очень хотелось сделать более-менее красивый пример, а не полуфабрикат…

<script type="text/javascript">
$(document).ready(function(){

// ---- DRAGGABLES & DROPPABLES -----
$("div.products").draggable({
  helper: clone,
  opacity: 0.5
});

$("#basket").droppable({
  accept: ".products",
  activeClass: "droppable-active",
  hoverClass: "droppable-hover",
  drop: function(ev, ui) {
    var code = $(ui.draggable.element)
    .find("img").attr("id");
    if($(this).find("div[@id="+ code +"]")
      .html()==null) {
      var name = $(ui.draggable.element)
      .find("img").attr("alt");
      $(this).append("
<div class="basket" id=" + code + ">
<input type="text" class="qnt"/> " + name +
"<img src="droppable-delete.gif" class="delete"
alt="Удалить" /></div>
");
    }
  // *******************
  $(".delete").click(function () {
    $(this).parent().remove();
  });
  // *******************
  // *******************
  $("#buy").click(function () {
    var databox = new Array();
    $("#basket").find("input[@type=text]")
      .each(function(){
      var qnt = $(this).attr("value");
      if(qnt===undefined) { qnt = 0; }
      	var text = $(this).parent().text();
      	databox[databox.length] =  text + " - " + qnt;
      });
      data = databox.join(" кг, ");
      $("#buyResult").html("Вы заказали:" + data +
" кгСпасибо за покупку!");
    });
  // ****************
  }
});
// ------ DRAGGABLES & DROPPABLES ------
});
</script>

Как обычно используем $(document).ready(function(){…}); которая отслеживает момент готовности объектной модели документа (DOM). В нее «завернуто» все, что мы написали. И начнем разбираться дальше.

$("div.products").draggable({
  helper: clone,
  opacity: 0.5
});

Это уже должно быть немножко знакомо: выбираем набор элементов DIV, имеющих класс .products и делаем любой из них свободно перемещаемым, задавая при этом некоторые опции. helper: clone – при перемещении элемента он останется на месте, а перемещать с помошью мыши мы будем его клон, opacity: 0.5 – прозрачность которого во время перемещения будет 0,5.

Дальше буду приводить код небольшими кусочками, чтобы было легче разбираться.

$("#basket").droppable({
  accept: ".products",
  activeClass: "droppable-active",
  hoverClass: "droppable-hover"

Выбираем элемент с идентификатором basket и делаем его droppable – туда будем «сбрасывать» перемещаемые элементы. Далее устанавливаем необходимые опции:
accept: «.products» – «сбросить» мы можем только элементы, имеющие класс products.
activeClass: «droppable-active» – имя класса, который будет применен к #basket во время перемещения любого из элементов с классом .products, но до того, как перемещаемый элемент окажется «в зоне действия» элемента #basket.
hoverClass: «droppable-hover» – все тоже самое, только класс будет применен тогда, когда перемещаемый элемент попадет в «зону действия» элемента #basket.
В опции drop – устанавливается функция, которая должна будет выполниться в момент, когда мы «сбросили» перемещаемый элемент. Простор для фантазии – обрабатывайте данные как угодно. Я кратко немного прокомментирую, что написано дальше.

var code = $(ui.draggable.element)
.find("img").attr("id");

Мы обращаемся к перемещаемому элементу, находим в нем (именно в нем) элемент img и получаем значение его атрибута id. Сохраняем в переменной code.

if($(this).find("div[@id="+ code +"]").html()==null)

Здесь будем проверять, нет ли уже в нашей корзине товара с таким же id. Для этого обратимся к элементу, который представляет собой нашу корзину (this в данном случае тоже самое, что и #basket), найдем элемент div с id равным id перемещаемого элемента (хранится в переменной code) и получим его HTML-код. Сравним с null. Если условие верное, значит такого продукта в корзине еще нет и мы можем выполнять следующие операторы, чтобы добавить товар в корзину.

var name = $(ui.draggable.element)
.find("img").attr("alt");

Обращаемся к перемещаемому элементу (это уже делали, правда?), ищем img, получаем значение атрибута alt, где у нас хранится название товара.
Теперь осталось только сформировать нужный HTML-код и добавить его в корзину, т.е. в элемент #basket.

$(this).append('<p class="basket" id=' + code + '>
<input class="qnt" type="text" /> ' + name +
'<img src="droppable-delete.gif" class="delete" alt="Удалить" />');</p>

Тут вроде бы все достаточно понятно. И осталось написать еще пару вспомогательных функций, чтобы пример был хоть немного действующим. Приводить их еще раз тут не буду (можете посмотреть их в полном коде), просто поясню, что первая обрабатывает клик мышкой на картинке удаления товара из корзины и собственно удаляет выбранный элемент div. А вторая обходит все имеющиеся текстовые поля ввода, собирает их значения в массив, объединяет массив в строку и выводит результат в виде HTML-кода в элемент #buyResult.

Поделиться в FaceBookПоделиться ВКонтактеДобавить в TwitterПоделиться в Моём МиреСохранить закладку в GoogleОтправить в Живую ленту GoogleДобавить в Яндекс.ЗакладкиПоделиться в ОдноклассникахОпубликовать в LiveJournal