При перетаскивании элементов в обработчик событий перетаскивания передается объект типа DragEvent. Этот тип наследует свойства от
MouseEvent
и соответственно типа Event
, но в дополнение к ним также определяет свойство dataTransfer. Это свойство
представляет перетаскиваемые данные в виде объекта DataTransfer.
Тип DataTransfer
определяет ряд свойств, которые позволяют получить информацию о получаемых данных или настроить их перетаскивание:
dropEffect: получает или устанавливает тип операции перетаскивания. Может принимать значения:
copy
: создается копия перетаскиваемых данных, и эта копия помещается на новую позицию
move
: данные полностью перемещаются на новую позицию
link
: создается ссылка на источник данных
none
: данные не перетскиваются
effectAllowed: устанавливает возможные типы операций. Может принимать следующие значения
none
: элемент не перетаскивается
copy
: элемент может копироваться на новую позицию
copyLink
: допустимо копирование элемента или создание ссылки на него
copyMove
: допустимо копирование или перемещение элемента
link
: допустимо создание ссылки на перетаскиваемый элемент
linkMove
: допустимо перемещение элемента или создание ссылки на него
move
: допустимо перемещение элемента на новую позицию
all
: все операции допустимы
uninitialized
: значение по умолчанию, если это свойство не установлено. Эквивалентно all
files: содержит список всех локальных файлов, доступных для передачи данных. Если операция перетаскивания не предполагает перетаскивание файлов, это свойство представляет собой пустой список.
items: предоставляет объект DataTransferItemList, который представляет собой список всех данных перетаскивания.
types: массив строк, задающих форматы, заданные в событии перетаскивания.
Для управления данными при перетаскиваниии тип DataTransfer определяет следующие методы:
clearData(): удаляет данные, связанные с объектом DataTransfer
getData(format): извлекает данные объекта DataTransfer. В качестве параметра передается формат данных. Возвращаются данные указанного формата. Если данные указанного формата не установлены, возвращает пустую строку
setData(format, data): устанавливает для объекта DataTransfer данные data, которые относятся к формату format. Если в DataTransfer уже есть данные указанного формата, то новые данные заменяют те, которые имелись ранее.
setDragImage(imgElement, xOffset, yOffset): устанавливает изображение, применяемое при перетаскивании. Первый параметр - imgElement
представляет элемент <img>
, используемый в качестве источника изображения. А параметры xOffset, yOffset задают соответственно смещения внутри изображения по оси x и y
В частности, методы setData()/getData()
позволяют нам легко установить и получить нужные данные при перетаскивании элементов. Например:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>METANIT.COM</title> <style> #target {width: 200px;height: 150px; border: #ccc 1px dashed;} #target.dragover {border-color:#000;} .item {width:50px;height:50px; display: inline-block; margin:5px;} </style> </head> <body> <div class="item" style="background-color: red;" draggable="true"></div> <div class="item" style="background-color: blue;" draggable="true"></div> <div id="target"></div> <script> const items = document.getElementsByClassName("item"); // устанавливаем обработчик перетаскивания элемента for (item of items) { item.addEventListener("dragstart", (e) => { // в качестве перетаскиваемых данных устанавливаем html-код элемента e.dataTransfer.setData("text/html", e.target.outerHTML); }); } const target = document.getElementById("target"); target.addEventListener("dragover", (e) => e.preventDefault()); // при заходе и выходе из целевой области меняем класс target.addEventListener("dragenter", (e) => e.target.classList.add("dragover")); target.addEventListener("dragleave", (e) => e.target.classList.remove("dragover")); // при отпускании элемента добавляем его на целевую область target.addEventListener("drop", (e) => { e.srcElement.innerHTML += e.dataTransfer.getData("text/html"); e.target.classList.remove("dragover"); }); </script> </body> </html>
Перетаскиваемые элементы здесь определены с классом item - это синий и красный квадраты. Перетаскивание осуществляется на элемент <div id="target">
Сначала регистрируется обработчик события dragstart для всех перемещаемых элементов item. В этом обработчике через параметр
и его свойство dataTransfer
можно получить объект DataTransfer:
const items = document.getElementsByClassName("item"); // устанавливаем обработчик перетаскивания элемента for (item of items) { item.addEventListener("dragstart", (e) => { // в качестве перетаскиваемых данных устанавливаем html-код элемента e.dataTransfer.setData("text/html", e.target.outerHTML); }); }
Объект DataTransfer представляет данные, которые перетаскиваются. Эти данные можно определить с помощью метода setData():
e.dataTransfer.setData("text/html", event.target.outerHTML);
Здесь e.target
представляет перемещаемый элемент (у которого установлен атрибут draggable
). А e.target.outerHTML
представляет html-код этого элемента. То есть таким образом мы будем перемещать html-код, а перемещаемое содержимое будет иметь тип "text/html"
На целевой области перетаскивания (в элементе target) эти данные затем можно получить с помощью метода getData(). В примере выше это делается в обработчике события drop, когда пользователь отпустил перетаскиваемый элемент на целевую область:
target.addEventListener("drop", (e) => { e.srcElement.innerHTML += e.dataTransfer.getData("text/html"); e.target.classList.remove("dragover"); });
В данном случае мы берем перетаскиваемые данные (html-код элемента) и добавляем их в элемент target.
Кроме того, для визуального эффекта, когда перетаскиваемый элемент пересекает границу целевой области, переключаем класс loading:
target.addEventListener("dragenter", (e) => e.target.classList.add("dragover")); target.addEventListener("dragleave", (e) => e.target.classList.remove("dragover"));
Таким образом, мы сможем перемещать элементы item на элемент target: