JavaScript Drag-and-Drop: Упрощённый подход с интерактивным примером
В этом руководстве мы рассмотрим функциональность перетаскивания (drag-and-drop) в JavaScript — мощную возможность, которая повышает интерактивность веб-страниц. Мы начнём с обсуждения основных концепций и алгоритмов, обеспечивающих перетаскивание, а затем перейдём к практическому примеру, где вы сможете увидеть эти идеи в действии. Этот пример включает иконку лампочки, которую можно перетащить в тёмную область, чтобы она загорелась.
Что такое перетаскивание?
Перетаскивание — это взаимодействие с пользовательским интерфейсом, которое позволяет пользователю захватить объект и переместить его в другое место на экране. Такое взаимодействие широко используется при управлении файлами на компьютере, расстановке предметов в играх или в онлайн-редакторах.
Основные концепции перетаскивания в JavaScript
Алгоритм перетаскивания
- Начало перетаскивания:
- Процесс начинается, когда пользователь нажимает на элемент и удерживает кнопку мыши.
- Перемещение элемента:
- По мере движения мыши элемент следует за курсором по экрану.
- Отпускание элемента:
- Элемент отпускается, когда пользователь отпускает кнопку мыши, помещая его в новую позицию.
Понимание зон сброса (Droppables)
Зоны сброса (droppables) — это области, предназначенные для приёма перетаскиваемых элементов. Эти области обнаруживают, когда перетаскиваемый объект находится над ними, и могут запускать определённые действия в ответ.
INFO
Убедитесь, что ваш функционал перетаскивания удобен для сенсорных экранов. Пользователи мобильных устройств должны иметь возможность перетаскивать элементы жестами. Рассмотрите возможность реализации сенсорных событий (touchstart, touchmove, touchend) или использования лёгкой библиотеки для кросс-устройственной совместимости.
Интерактивный пример: Светлая и тёмная область
Давайте применим теорию на практике с помощью простого, но интерактивного примера. В качестве перетаскиваемого объекта мы будем использовать иконку лампочки. Когда эта иконка перемещается над тёмной областью, она загорается, имитируя включение света.
Настройка HTML и CSS
Сначала мы определяем базовую структуру и стиль. Мы добавляем тёмный блок и иконку лампочки.
Структура HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Interactive Lighting with Drag and Drop</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" />
<style>
#darkArea {
width: 300px;
height: 300px;
background-color: #333;
position: relative;
margin-top: 20px;
}
#lightIcon {
font-size: 48px;
color: #ccc;
cursor: pointer;
position: absolute;
}
</style>
</head>
<body>
<div id="main">
<div id="darkArea"></div>
<i id="lightIcon" class="fas fa-lightbulb"></i>
</div>
<script>
// JavaScript will be added here.
</script>
</body>
</html>Реализация JavaScript
Теперь добавим функциональность, чтобы сделать лампочку перетаскиваемой и реагирующей на тёмную область.
Объяснение кода JavaScript
<script>
// Get references to the light bulb icon and the dark area on the webpage
var lightIcon = document.getElementById("lightIcon");
var darkArea = document.getElementById("darkArea");
// Variables to track whether the dragging is active and to store position data
var active = false;
var initialX, initialY, currentX, currentY, xOffset = 0, yOffset = 0;
// Listen for the mouse down event on the light bulb icon
lightIcon.addEventListener("mousedown", function(e) {
// Record the starting position of the mouse and adjust by any existing offset
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
// Set the active flag to true, indicating that dragging has started
active = true;
});
// Listen for mouse movement across the entire document
document.addEventListener("mousemove", function(e) {
// If not dragging, don't do anything
if (!active) return;
// Calculate the new position of the mouse
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
// Update the offset with the new position
xOffset = currentX;
yOffset = currentY;
// Move the light bulb icon to the new position
lightIcon.style.transform = "translate3d(" + currentX + "px, " + currentY + "px, 0)";
});
// Listen for the mouse up event across the entire document
document.addEventListener("mouseup", function() {
// Save the final position of the light bulb
initialX = currentX;
initialY = currentY;
// Set the active flag to false, indicating dragging has ended
active = false;
// Check if the light bulb is inside the dark area
if (isInside(darkArea, lightIcon)) {
// Change the background color of the dark area to yellow
darkArea.style.backgroundColor = "yellow";
// Change the color of the light bulb to yellow
lightIcon.style.color = "yellow";
} else {
// Revert the dark area's color to dark
darkArea.style.backgroundColor = "#333";
// Revert the light bulb's color to gray
lightIcon.style.color = "#ccc";
}
});
// Function to check if the light bulb is inside the dark area
function isInside(container, element) {
// Get the position of the container and the element
var containerRect = container.getBoundingClientRect();
var elementRect = element.getBoundingClientRect();
// Return true if the element is within the container's boundaries
return (
elementRect.left >= containerRect.left &&
elementRect.right <= containerRect.right &&
elementRect.top >= containerRect.top &&
elementRect.bottom <= containerRect.bottom
);
}
</script>Этот скрипт делает иконку лампочки на экране перемещаемой с помощью мыши. Вы можете нажать на лампочку, перетащить её и увидеть, как она взаимодействует с тёмной областью на экране. Вот что делает каждая часть скрипта простыми словами:
Подготовка: Сначала скрипт находит иконку лампочки и тёмную область на вашей веб-странице. Он также настраивает правила для отслеживания движения мыши.
Начало перетаскивания:
- Когда вы нажимаете кнопку мыши на лампочке, скрипт запоминает начальную точку. Это помогает ему понять, насколько далеко вы переместили лампочку.
Перемещение лампочки:
- Пока вы удерживаете кнопку мыши и двигаете курсором, скрипт заставляет лампочку следовать за мышью. Он постоянно обновляет позицию лампочки, чтобы она совпадала с положением курсора.
Отпускание лампочки:
- Когда вы отпускаете кнопку мыши, скрипт проверяет, находится ли лампочка над тёмной областью. Если да, тёмная область загорается (становится жёлтой), а цвет лампочки также меняется, показывая, что она включена. Если лампочка не над тёмной областью, всё возвращается в исходное состояние.
Проверка позиции:
- Существует специальный набор правил (функция
isInside), который помогает скрипту определить, находится ли лампочка над тёмной областью. Он сравнивает позицию лампочки с границами тёмной области.
- Существует специальный набор правил (функция
INFO
Используйте translate3d в CSS-трансформациях для перетаскиваемых элементов. Он задействует ускорение GPU, что обеспечивает более плавное движение и снижает нагрузку на процессор, что критически важно для приложений с высокой производительностью.
Полный пример
Теперь самое время увидеть всё в действии:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Interactive Lighting with Drag and Drop</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" />
<style>
#darkArea {
width: 300px;
height: 300px;
background-color: #333;
position: relative;
margin-top: 20px;
}
#lightIcon {
font-size: 48px;
color: #ccc;
cursor: pointer;
position: absolute;
}
</style>
</head>
<body>
<div id="main">
<p>Move the light into the dark area to light it up!</p>
<div id="darkArea"></div>
<i id="lightIcon" class="fas fa-lightbulb"></i>
</div>
<script>
// Get references to the light bulb icon and the dark area on the webpage
var lightIcon = document.getElementById("lightIcon");
var darkArea = document.getElementById("darkArea");
// Variables to track whether the dragging is active and to store position data
var active = false;
var initialX,
initialY,
currentX,
currentY,
xOffset = 0,
yOffset = 0;
// Listen for the mouse down event on the light bulb icon
lightIcon.addEventListener("mousedown", function (e) {
// Record the starting position of the mouse and adjust by any existing offset
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
// Set the active flag to true, indicating that dragging has started
active = true;
});
// Listen for mouse movement across the entire document
document.addEventListener("mousemove", function (e) {
// If not dragging, don't do anything
if (!active) return;
// Calculate the new position of the mouse
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
// Update the offset with the new position
xOffset = currentX;
yOffset = currentY;
// Move the light bulb icon to the new position
lightIcon.style.transform = "translate3d(" + currentX + "px, " + currentY + "px, 0)";
});
// Listen for the mouse up event across the entire document
document.addEventListener("mouseup", function () {
// Save the final position of the light bulb
initialX = currentX;
initialY = currentY;
// Set the active flag to false, indicating dragging has ended
active = false;
// Check if the light bulb is inside the dark area
if (isInside(darkArea, lightIcon)) {
// Change the background color of the dark area to yellow
darkArea.style.backgroundColor = "yellow";
lightIcon.style.color = "yellow";
} else {
// Revert the dark area's color to dark
darkArea.style.backgroundColor = "#333";
// Revert the light bulb's color to gray
lightIcon.style.color = "#ccc";
}
});
// Function to check if the light bulb is inside the dark area
function isInside(container, element) {
// Get the position of the container and the element
var containerRect = container.getBoundingClientRect();
var elementRect = element.getBoundingClientRect();
// Return true if the element is within the container's boundaries
return elementRect.left >= containerRect.left && elementRect.right <= containerRect.right && elementRect.top >= containerRect.top && elementRect.bottom <= containerRect.bottom;
}
</script>
</body>
</html>Основные используемые события мыши:
mousedown: Это событие срабатывает, когда пользователь нажимает кнопку мыши над иконкой лампочки. Оно отмечает начало перетаскивания и записывает начальную позицию курсора.mousemove: Это событие срабатывает при движении мыши. Если перетаскивание активно (т.е. кнопка мыши всё ещё нажата), оно вычисляет новую позицию иконки на основе движения курсора и обновляет положение лампочки на экране.mouseup: Это событие происходит, когда пользователь отпускает кнопку мыши, отмечая конец перетаскивания. Оно проверяет, находится ли лампочка в пределах тёмной области, чтобы решить, менять ли её фоновый цвет.
Как мы узнали в статье События мыши, эти события являются фундаментальными для создания интерактивного функционала перетаскивания, позволяя динамически перемещать элементы на веб-странице и взаимодействовать с ними с помощью мыши.
Заключение
Действия перетаскивания могут сделать ваши сайты более удобными и привлекательными. Освоив простые идеи и попробовав их на реальных примерах, вы сможете эффективно использовать эти возможности. Это сделает ваши сайты более увлекательными и интерактивными.
Практика
Какие утверждения о функциональности перетаскивания в JavaScript являются верными?