JavaScript Drag-and-Drop: Упрощённый подход с интерактивным примером
In this tutorial, we'll explore the drag-and-drop functionality in JavaScript, a powerful feature that enhances interactivity on web pages. We'll begin by
В этом руководстве мы рассмотрим функциональность перетаскивания (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 являются верными?