Найти в Дзене
CyberHaus

JavaScript Drag-and-Drop

В этой статье я расскажу о том, как работает перетаскивание объектов в HTML5.

Для начала создадим файл index.html, папки js и css. В папке js создадим файл common.js, а в папке css создадим файл style.css

Структура проекта
Структура проекта

Теперь напишем разметку в файле index.html

HTML разметка index.html
HTML разметка index.html

Теперь напишем стили в файле style.css

файл style.css
файл style.css

В результате в браузере увидим следующее

Результат в браузере
Результат в браузере

Перейдем в файл common.js и начнем писать код. В начале повесим на объект window событие load, которое будет вызвано после того, как страница полностью загрузится.

событие load
событие load

Затем объявим необходимые переменные:

объявление переменных
объявление переменных

Переменная count - это счетчик для того, чтобы можно было присваивать уникальные id перемещаемым элементам. В переменной posX сохраним позицию курсора по иксу относительно панели с классом p-right, а в переменной posY сохраним позицию по игреку. В переменной blockPosX сохраним позицию курсора по иксу относительно перемещаемого элемента, а в переменную blockPosY сохраним позицию по игреку. В переменной panelLeft сохраним элемент с классом p-left, а в переменной panelRight сохраним элемент с классом p-right.

Теперь на panelLeft повесим событие mousedown и проверим, имеется ли класс block у элемента, на котором было вызвано событие mousedown. Если это так, меняем курсор и сохраняем в переменную blockPosX позицию курсора по иксу относительно элемента, а в переменную blockPosY сохраняем позицию по игреку.

событие mousedown на левом блоке div
событие mousedown на левом блоке div

Так же повесим на div элемент panelLeft событие mouseup. Проверим, существует ли у элемента класс block и, если существует. изменим курсор.

событие mouseup на левом блоке div
событие mouseup на левом блоке div

Затем повесим на panelLeft событие dragstart - это событие вызывается в тот момент, когда начинается перемещение элемента мышкой. При вызове этого события сохраним id перемещаемого элемента при помощи метода setData() объекта dataTransfer. Первым параметром передаем в метод тип сохраняемых данных, в нашем случае это простой текст, а вторым параметром - собственно id элемента.

событие dragstart на левом блоке div
событие dragstart на левом блоке div

Перейдем к событию dragend и повесим его также на элемент panelLeft. Это событие вызывается в тот момент, когда перемещение элемента завершено. При возникновении события dragend изменим курсор.

событие dragend на левом блоке div
событие dragend на левом блоке div

Теперь мы повесим точно такие же события на элемент panelRight

событие mousedown на правом блоке div
событие mousedown на правом блоке div
событие mouseup на правом блоке div
событие mouseup на правом блоке div
событие dragstart на правом блоке div
событие dragstart на правом блоке div
событие dragend на правом блоке div
событие dragend на правом блоке div

Также повесим на блок panelRight событие dragenter - это событие вызывается в тот момент, когда перемещаемый элемент оказывается над блоком для перемещения элемента. В нашем случае это div с классом panelRight. Нам не требуется выполнять никаких действий при вызове события dragenter, поэтому просто вызовим e.preventDefault().

событие dragenter на правом блоке div
событие dragenter на правом блоке div

Еще добавим событие dragover - это событие возникает в тот момент, когда перетаскиваемый элемент перемещается над областью, в которую должен быть помещён. В этом событии первым делом вызываем метод e.preventDefault(), а затем сохраняем в переменные координаты курсора.

событие dragover на правом блоке div
событие dragover на правом блоке div

Завершаем всё добавлением события drop - это событие возникает в тот момент когда, объект перемещен в необходимую область. В нашем случае в div с классом panelRight. В первую очередь получим id перемещаемого элемента, а затем получим сам элемент. Далее проверяем: если атрибут элемента data-type равен proto, то это значит, что нам необходимо дублировать элемент в правый div. Увеличиваем переменную count, клонируем элемент методом cloneNode(), меняем id, добавляем к существующему id знак подчеркивания и переменную count. Значение атрибута data-type меняем на elem. Добавляем класс pos и меняем вид курсора. Далее идет проверка, является ли значение атрибута data-type elem. и, если это так, значит перемещаемый элемент уже находится в правом элементе div. А это значит. нам надо просто его переместить на новое место. Свойству position задаем значение absolute. Для предотвращения ухода границ блока за пределы блока panelRight проверим, чтобы переменные posX и posY были не меньше нуля. Если какое-либо условие срабатывает, просто устанавливаем переменную в ноль. В конце присваиваем свойству top значение posX, а свойству left значение posY.

событие drop на правом блоке div
событие drop на правом блоке div

В браузере наше приложение будет выглядеть следующим образом:

результат перемещения из правого блока в левый
результат перемещения из правого блока в левый
результат перемещения в левом блоке
результат перемещения в левом блоке

Если надо просто переместить элемент из левого блока div в правый не дублируя, тогда в конец блока if(el.getAttribute(‘data-type’) == ‘proto’) добавим строчку el.remove();

А строку cpElem.setAttribute(‘id’, id+”_”+count) удаляем, т.к. менять id в данном случае не понадобится. На этом всё!

Пример