Drag-and-Drop API

Перетаскивание элементов с помощью Drag-and-Drop API

Последнее обновление: 13.11.2023

Drag-and-Drop API позволяет переносить различные элементы мышью на определенную позицию на веб-странице. При перемещении элементов у нас есть источник перемещения - элемент, который перемещаем мышью, и цель перемещения - целевая область на веб-странице (другой элемент), на которую надо переместить источник перемещения.

Чтобы определить элемент на веб-странице, который можно перемещать (источник перетаскивания), нужно для этого элемент определить атрибут draggable со значением true. Теоретически в качестве перетаскиваемого элемента может выступать любой элемент веб-страницы. Например:

<div style="width:50px;height:50px; background-color: red;" draggable="true"></div>

По умолчанию элементы не являются перетаскиваемыми.

В качестве цели перетаскиванию может служить произвольный элемент веб-страницы.

После того, как элемент определен как перемещаемый, надо также определить действия, выполняемые при перемещении элемента. Во время операции перетаскивания запускается ряд различных событий:

  • dragstart: генерируется, когда начинается перетаскивание элемента

  • drag: генерируется постоянно по мере того, как элемент перетаскивается

  • dragend: генерируется, когда перетаскивание элемента завершено

  • dragenter: генерируется, когда элемент входит в границы целевой области

  • dragover: генерируется постоянно (несколько раз в секунду) по мере того, как элемент перетаскивается над целевой областью

  • dragleave: генерируется, когда элемент покидает целевую область

  • drop: генерируется, перетаскиваемый элемент отпускается на целевой области

Обработчики всех выше перечисленных событий перемещения в качестве параметра получают объект типа DragEvent. Этот тип наследует свойства от MouseEvent и соответственно типа Event

Обработчик события dragstart определяется для перетаскиваемого элемента, а обработчики остальных событий определяются для области, на которую надо переместить элемент. Например:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
    <style>
    #source { width:50px; height:50px; background-color: red; display: inline-block;}
    #target {width: 200px; height: 150px; overflow: hidden; border: #ccc 1px dashed;}
    div{margin:5px;}
    </style>
</head>
<body>
<div id="source" draggable="true"></div>
<div id="target"></div>
<script>
const source = document.getElementById("source");
source.addEventListener("dragstart", () => console.log("Drag operation started"));

const target = document.getElementById("target");
target.addEventListener("dragover", (event) => {  
    event.preventDefault();  
    console.log("Dragover operation");
});
target.addEventListener("drop", () => console.log("Drag operation finished"));
</script>
</body>
</html>

В данном случае перемещаемый элемент имеет идентификатор source, и для него регистрируется обработчик события "dragstart". Оно будет возникать, когда мы захватим элемент указателем мыши и начнем перемещать.

Область, на которую перемещаем элемент, представляет другой элемент с идентификатором target. Для демонстрации для него регистрируем обработчики событий "dragover" и "drop". Событие "dragover" будет возникать, когда элемент item будет перемещаться поверх элемента target. Чтобы предупредить генерацию события "drop" во время перемещения, в обработчике этого события вызывается метод event.preventDefault(). Когда мы отпустим элемент item на элемент target, будет сгенерировано событие "drop".

Drag&Drop API в JavaScript

Однако в выше приведенном примере в реальности перетаскиваемый элемент пока никуда не перемещается. Потому что нам надо установать перемещаемые данные и при завершении перемещения получить их. Например:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
    <style>
    #source { width:50px; height:50px; background-color: red; display: inline-block;}
    #target {width: 200px; height: 150px; overflow: hidden; border: #ccc 1px dashed;}
    div{margin:5px;}
    </style>
</head>
<body>
<div id="source" draggable="true"></div>
<div id="target"></div>
<script>
let dragged = null; // перемещенные данные
// источник перемещения
const source = document.getElementById("source")
// в обработчике устанавливаем ссылку на перетаскиваемый элемент
source.addEventListener("dragstart", (e) => dragged = e.target);

// целевая область перемещения
const target = document.getElementById("target");
// предупреждаем событие drop
target.addEventListener("dragover", (e) => e.preventDefault());
// копируем перетаскиваемый элемент и помещаем его копию на целевую область
target.addEventListener("drop", (e) => e.target.appendChild(dragged.cloneNode()));
</script>
</body>
</html>

Здесь при начале перетаскивания мы сохраняем перемещаемый объект в переменную dragged

source.addEventListener("dragstart", (e) => dragged = e.target);

При окончании перетаскивания помещаем копию элемента source на элемент target

target.addEventListener("drop", (e) => e.target.appendChild(dragged.cloneNode()));

Таким образом, при перетаскивании на область target будут добавляться копии элемента source:

Drag-and-Drop API в JavaScript

В качестве альтернативы мы можем выполнить полное перемещение перетаскиваемого элемента:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
    <style>
    #source { width:50px; height:50px; background-color: red; display: inline-block;}
    #target {width: 200px; height: 150px; overflow: hidden; border: #ccc 1px dashed;}
    div{margin:5px;}
    </style>
</head>
<body>
<div id="target"></div>
<div id="source" draggable="true"></div>
<script>
let dragged = null; // перемещенные данные
// источник перемещения
const source = document.getElementById("source")
// в обработчике устанавливаем ссылку на перетаскиваемый элемент
source.addEventListener("dragstart", (e) => dragged = e.target);

// целевая область перемещения
const target = document.getElementById("target");
// предупреждаем событие drop
target.addEventListener("dragover", (e) => e.preventDefault());
// полностью перемещаем перетаскиваемый элемент на целевую область
target.addEventListener("drop", (e) => {
    dragged.parentNode.removeChild(dragged);
    e.target.appendChild(dragged);
});
</script>
</body>
</html>

Здесь в обработчике "drop" сначала удаляем перетаскиваемый элемент из родительского контейнера (в данном случае элемента body), а затем добавляем его на целевую область:

target.addEventListener("drop", (e) => {
    dragged.parentNode.removeChild(dragged);
    e.target.appendChild(dragged);
});
Перемещение элементов с помощью Drag-and-Drop API в JavaScript
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850