При перетаскивании элементов в обработчик событий перетаскивания передается объект типа 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: