• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

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

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Front-End Drag and Drop: Looks Simple, But Full of Hidden Pitfalls

Sascha Оффлайн

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,549
Баллы
155
Drag-and-drop is one of the most common interactions in front-end development:
From dragging files in Baidu Netdisk to moving objects in Figma’s canvas, it’s everywhere.

Many developers think — isn’t drag-and-drop just mousedown + mousemove + mouseup?
Three lines of code and done!

But once you implement it in a real production environment, the pitfalls start appearing one after another:

  • Different event models between PC and mobile
  • Elements “flying” outside their containers
  • Events lost when dragging over iframes
  • Conflicts between drag and scroll on mobile devices
  • State loss when using frameworks like Vue or React

Building a working drag-and-drop is easy.
Building a robust and smooth drag-and-drop experience is hard.

Today, let’s break down how to implement a solid drag-and-drop system — and avoid the most common pitfalls.

The Basic Principle of Drag-and-Drop


Drag-and-drop relies on three core events:

  1. mousedown — Start dragging
  2. mousemove — Move the element
  3. mouseup — End dragging

Here’s the simplest implementation:


const box = document.getElementById('box');
let isDragging = false;
let offsetX = 0, offsetY = 0;

// Start dragging
box.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - box.offsetLeft;
offsetY = e.clientY - box.offsetTop;
});

// Move the element
document.addEventListener('mousemove', (e) => {
if (isDragging) {
box.style.left = (e.clientX - offsetX) + 'px';
box.style.top = (e.clientY - offsetY) + 'px';
}
});

// Stop dragging
document.addEventListener('mouseup', () => {
isDragging = false;
});




👉 Live demo:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



In short: drag-and-drop simply means continuously updating an element’s left/top while moving the mouse.

Common Pitfalls in Real Development


Here are some of the most frequent issues developers run into:

1. Multi-Device Compatibility


Different devices have different event systems:

  • PC → uses mouse events (mousedown, mousemove, mouseup)
  • Mobile → uses touch events (touchstart, touchmove, touchend)

function isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ||
('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0);
}



2. Boundary Constraints


You need to keep draggable elements within their containers to avoid them flying off-screen.

Solution:


updatePosition(newX, newY) {
const containerRect = this.container.getBoundingClientRect();
const elementRect = this.element.getBoundingClientRect();

const minX = 0;
const minY = 0;
const maxX = containerRect.width - elementRect.width;
const maxY = containerRect.height - elementRect.height;

newX = Math.max(minX, Math.min(newX, maxX));
newY = Math.max(minY, Math.min(newY, maxY));

this.element.style.left = newX + 'px';
this.element.style.top = newY + 'px';
}



3. iframe Compatibility Issues


When dragging across an iframe, mouse events are lost as soon as the cursor enters the iframe area.
A common workaround: temporarily disable iframe pointer events during drag.


const iframes = document.getElementsByTagName('iframe');
for (const iframe of iframes) {
iframe.style.pointerEvents = 'none';
}



4. Framework Compatibility


In frameworks like Vue or React, component re-renders can cause drag state loss.
You can use MutationObserver to watch for DOM changes and prevent style resets.


this.observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === "style" &&
element.style.display === "none") {
element.style.display = "block";
}
});
});

this.observer.observe(element, {
attributes: true,
attributeFilter: ["style"],
});



5. Scroll Conflicts on Mobile


On touch devices, dragging often triggers page scrolling.


handleTouch(event) {
event.preventDefault();
event.stopPropagation();

this.startDrag(event);
}



Advanced Features


Besides the basics, real-world drag-and-drop often requires:

  • Grid snapping – automatically align to a grid
  • Edge snapping – auto-stick to edges
  • Position persistence – remember the element’s position after refresh

These features require additional logic and careful design.

A Better Solution: drag-kit


After all these pitfalls, you can see that building a robust drag-and-drop solution isn’t trivial.
It involves event abstraction, boundary control, iframe compatibility, performance optimization, and framework integration.

That’s why it’s better to use a mature library —

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Key Features of drag-kit

  1. Plug and play – ready to use in minutes
  2. Cross-platform – automatically handles PC, mobile, and tablets
  3. Rich features – built-in boundary, grid, and snap support
  4. Framework friendly – works with Vue 2/3 and React
  5. Performance optimized – smooth and lag-free
  6. TypeScript ready
Quick Start


import { createDraggable } from 'drag-kit';

// Basic usage
createDraggable('myElement');

// Advanced configuration
createDraggable('myElement', {
mode: 'screen',
initialPosition: { x: '100px', y: '200px' },
lockAxis: 'y',
gridSize: 50,
snapMode: 'auto',
shouldSave: true,
onDragStart: (el) => console.log('Start drag', el),
onDrag: (el) => console.log('Dragging', el),
onDragEnd: (el) => console.log('End drag', el)
});



Installation


npm install drag-kit




Vue 3 Example


import { onMounted } from 'vue';
import { createDraggable } from 'drag-kit';

export default {
setup() {
onMounted(() => {
createDraggable('draggableElement', {
initialPosition: { x: '100px', y: '200px' }
});
});
}
};



Conclusion


While drag-and-drop seems simple in theory, it becomes complex in production due to:

  • Multi-device event differences
  • Boundary handling
  • iframe compatibility
  • Framework state loss
  • Mobile scroll conflicts

If you’re just building a quick demo — three lines of code are enough.
But if you’re building for production, a mature library like drag-kit saves you time, avoids pitfalls, and delivers a smooth, stable, and professional drag-and-drop experience.

👉 GitHub:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.





Источник:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу