В этой заметка реализуем кастомный drag-and-drop на JavaScript с помощью обработки событий мыши.
See the Pen dnd by FurryCat (@mohnatus-the-lessful) on CodePen.
Верстка
<div id='dnd-container'>
<div id='dnd-item'></div>
</div>
Стили
#dnd-container {
width:100%;
height:400px;
background: #eee;
border: 2px solid #000;
position:relative;
overflow:hidden;
}
#dnd-item {
width:30px;
height:30px;
border-radius:50%;
background: green;
position:absolute;
}
Скрипт
let dndContainer = document.getElementById('dnd-container');
let dndItem = document.getElementById('dnd-item');
// Мяч позиционируется относительно контейнера
// Находим координаты контейнера в документе
let containterRect = dndContainer.getBoundingClientRect();
// Координаты контейнера с учетом прокрутки страницы
let containerRectWithScroll = {};
containerRectWithScroll.top = containterRect.top + pageYOffset;
containerRectWithScroll.left = containterRect.left + pageXOffset;
// Зажатие левой кнопки мыши на мяче
dndItem.onmousedown = function(e){
// Отменяем нативную реакцию браузера на событие перетаскивания
// так как мы реализуем ее самостоятельно
dndItem.ondragstart = function() {
return false;
}
// Находим текущие координаты мяча на странице
let itemRect = dndItem.getBoundingClientRect();
// Находим позицию мяча относительно контейнера
let itemRectInContainer = {};
itemRectInContainer.top = itemRect.top + pageYOffset
- containerRectWithScroll.top;
itemRectInContainer.left = itemRect.left + pageXOffset
- containerRectWithScroll.left;
// Находим смещение курсора от левого верхнего угла мяча при клике
let shiftX = e.pageX - itemRectInContainer.left;
let shiftY = e.pageY - itemRectInContainer.top;
// Передвигаем мяч
moveAt(e);
function moveAt(e){
// При достижении мячом границ контейнера передвижение прекращается
let itemLeftPosition = e.pageX - shiftX;
// Если достигнута левая граница контейнера
if (itemLeftPosition < 0) {
dndItem.style.left = 0;
} else {
let rightBoundary = dndContainer.clientWidth - dndItem.clientWidth;
// Если достигнута правая граница контейнер
if (itemLeftPosition > rightBoundary) {
dndItem.style.left = rightBoundary + 'px';
} else {
dndItem.style.left = itemLeftPosition + 'px';
}
}
let itemTopPosition = e.pageY - shiftY;
// Если достигнута верхняя граница контейнера
if (itemTopPosition < 0) {
dndItem.style.top = 0;
} else {
let bottomBoundary = dndContainer.clientHeight - dndItem.clientHeight;
// Если достигнута нижняя граница контейнера
if (itemTopPosition > bottomBoundary) {
dndItem.style.top = bottomBoundary + 'px';
} else {
dndItem.style.top = itemTopPosition + 'px';
}
}
}
// При движении мышью перемещаем мяч
dndContainer.onmousemove = function(e){
moveAt(e);
}
// При отпускании клавиши мыши прекращаем перемещение
dndContainer.onmouseup = function(){
dndContainer.onmousemove = null;
dndItem.onmouseup = null;
}
}
0 комментариев