Если вы хотите получить подробную информацию о том, как использовать JavaScript для создания интерфейсов с drag and drop, вот несколько заметок, которые могут быть полезны. Мы подробно рассмотрим Drag and Drop в теории, а, чтобы закрепить знания, реализуем интерфейс перетаскивания на JavaScript.
Теория. Что такое Drag and Drop API
Drag and drop API — это набор интерфейсов, позволяющих перетаскивать объекты на веб-странице. Это можно использовать для создания пользовательских интерфейсов, в которых объекты могут перемещаться пользователем.
Drag and drop «под капотом»
API состоит из трех основных частей:
- Первая часть — это интерфейс dragevent. Он используется для отслеживания перемещения перетаскиваемого объекта. Он также предоставляет информацию о месте падения объекта.
- Вторая часть — это интерфейс dragdata. Он содержит информацию о перетаскиваемых данных. С его помощью можно задать данные, которые будут переданы цели перетаскивания при перетаскивании объекта.
- Третья часть — интерфейс draglist. Он используется для отслеживания списка перетаскиваемых объектов. Он также предоставляет информацию о том, куда перетаскивается каждый объект.
Интерфейсы перетаскивания на Javascript легко создавать. В целом, создание интерфейса перетаскивания состоит из трех этапов.
- Во-первых, создайте слушатель событий, который будет выполняться, когда пользователь нажмет на элемент, который будет перетаскиваться. Слушатель должен вызывать функцию, которая хранит информацию о перетаскиваемом элементе.
- Во-вторых, создайте слушатель события onmousemove. Этот слушатель должен вызывать функцию, которая изменяет положение перетаскиваемого элемента в зависимости от положения мыши.
- Наконец, создайте слушателя события onmouseup. Этот слушатель должен вызывать функцию, которая останавливает перетаскивание элемента.
- Эти шаги можно выполнить с помощью всего нескольких строк кода. Например, этот код позволит вам перетаскивать любой элемент с идентификатором «draggable».
События при перемещении элемента
Давайте рассмотрим, какие события возникают при перемещении элемента.
- dragstart — вызывается при начале перетаскивания элемента.
- drangend — вызывается, когда перетаскивание завершается (отпускаем клавишу мыши)
- drag — вызывается при перетаскивании элемента (много раз)
- dragenter — вызывается, когда элемент попадает в допустимую зону
- dragover — вызывается, когда элемент перетаскивается в допустимую зону
- dragleave — вызывается, когда элемент покидает допустимую зону
- drop — вызывается, когда элемент отпускают в допустимую зону (отпускаем клавишу мыши)
Более наглядно события drag and drop представлены на картинке ниже:
Практика. Реализуем механизм Drag and Drop
Рассмотрим пример, как реализовать drag and drop на JS. В примере ниже, я создал три серых бокса, внутрь которых мы можем поместить синий элемент. При перетаскивании синий элемент меняет цвет на фиолетовый. При попадании элемента на бокс — он подсвечивается желтым.
Разметка
Создадим три бокса. Внутрь первого положим элемент item, который и будем перемещать.
<div class="container">
<div class="box">
<div class="item" draggable="true"></div>
</div>
<div class="box"></div>
<div class="box"></div>
</div>
Стили
Комментарии даны в коде.
.container {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
/* Стили для боксов */
.box {
width: 150px;
height: 150px;
background-color: #eee;
margin-right: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.box:last-child {
margin-right: 0;
}
/* Стили для перемещаемого элемента */
.item {
width: 100px;
height: 100px;
background-color: blue;
cursor: pointer;
}
/* Меняем курсор при перетаскивании */
.item:active {
cursor: grabbing;
}
/* При перетаскивания - меняем цвет */
.item--hold {
background-color: blueviolet;
}
/* При наведении на бокс - желтая подсветка */
.box--hovered {
background-color: rgba(255, 255, 0, 0.2);
}
/* Перетаскивании - скрываем элемент */
.item--hide {
display: none;
}
Скрипт
Комментарии даны в коде.
const item = document.querySelector(".item");
// Считываем все боксы в массив
const boxes = Array.from(document.querySelectorAll(".box"));
// Обработчик начала перетаскивания элемента
item.addEventListener("dragstart", dragstart);
// Обработчик завершения перетаскивания элемента
item.addEventListener("dragend", dragend);
// Обработчик для боксов
boxes.forEach((box) => {
// Когда заходим элементом в бокс
box.addEventListener("dragover", dragover);
// Когда отпускаем элемент на нужном боксе
box.addEventListener("drop", drop);
// Когда достигаем бокс
box.addEventListener("dragenter", dragenter);
// Когда покидаем бокс
box.addEventListener("dragleave", dragleave);
});
// Функция начала перетаскивания элемента
function dragstart(e) {
// Меняем цвет на фиолетовый
e.target.classList.add("item--hold");
// Удаляем элемент из бокса
setTimeout(() => e.target.classList.add("item--hide"), 0);
}
// Функция завершения перетаскивания элемента
function dragend(e) {
// Меняем цвет на синий
e.target.classList.remove("item--hold");
// Возвращаем элемент обратно
e.target.classList.remove("item--hide");
}
function dragover(e) {
e.preventDefault();
}
function drop(e) {
// Добавляем наш элемент в нужный бокс
e.target.append(item);
// Убираем желтую подсветку
e.target.classList.remove("box--hovered");
}
function dragenter(e) {
// Добавляем желтую подсветку
e.target.classList.add("box--hovered");
}
function dragleave(e) {
// Убираем желтую подсветку
e.target.classList.remove("box--hovered");
}
Алгоритм работы скрипта.
На перетаскиваемый элемент item навешиваем обработчики событий для:
- dragstart — начало перетаскивания. Меняем цвет item на фиолетовый и удаляем его из бокса.
- dragend — конец перетаскивания. Возвращаем item синий цвет и добавляем его в поток.
На боксы boxes навешиваются обработчики для:
- dragenter — пересечение item бокса. Задаем желтую подсветку боксу.
- dragover — попадание item в бокс. Сбрасываем стандартное поведение бокса.
- dragleave — покидание item бокса. Удаляем желтую подсветку бокса.
- drop — отпускание item в бокс. Добавляем item в выбранный бокс.
Полезные ссылки
- Демонстрация работы Drag and Drop: https://toni.codelab.pro/drag-and-drop/index.html
- Видео по теме статьи: https://codelab.pro/video/realizuem-mehanizm-drag-and-drop-na-javascript/
- Стартовый проект на Github: https://github.com/toni-wheel/youtube-base