js 实现拖动
实现基本拖动功能
使用 mousedown、mousemove 和 mouseup 事件实现基础拖动逻辑:
const draggable = document.getElementById('draggable');
let isDragging = false;
let offsetX, offsetY;
draggable.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - draggable.getBoundingClientRect().left;
offsetY = e.clientY - draggable.getBoundingClientRect().top;
draggable.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
draggable.style.left = `${e.clientX - offsetX}px`;
draggable.style.top = `${e.clientY - offsetY}px`;
});
document.addEventListener('mouseup', () => {
isDragging = false;
draggable.style.cursor = 'grab';
});
添加边界限制
防止元素被拖出可视区域:

document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const x = e.clientX - offsetX;
const y = e.clientY - offsetY;
const maxX = window.innerWidth - draggable.offsetWidth;
const maxY = window.innerHeight - draggable.offsetHeight;
draggable.style.left = `${Math.max(0, Math.min(x, maxX))}px`;
draggable.style.top = `${Math.max(0, Math.min(y, maxY))}px`;
});
支持触摸设备
添加触摸事件支持:
draggable.addEventListener('touchstart', (e) => {
isDragging = true;
const touch = e.touches[0];
offsetX = touch.clientX - draggable.getBoundingClientRect().left;
offsetY = touch.clientY - draggable.getBoundingClientRect().top;
});
document.addEventListener('touchmove', (e) => {
if (!isDragging) return;
const touch = e.touches[0];
// 使用与鼠标相同的移动逻辑
});
使用 CSS 优化体验
添加基础样式提升拖动体验:

#draggable {
position: absolute;
cursor: grab;
user-select: none;
touch-action: none;
}
#draggable:active {
cursor: grabbing;
}
封装为可复用函数
创建通用拖动函数:
function makeDraggable(element) {
let isDragging = false;
let offsetX, offsetY;
const startDrag = (clientX, clientY) => {
const rect = element.getBoundingClientRect();
offsetX = clientX - rect.left;
offsetY = clientY - rect.top;
isDragging = true;
};
const moveDrag = (clientX, clientY) => {
if (!isDragging) return;
element.style.left = `${clientX - offsetX}px`;
element.style.top = `${clientY - offsetY}px`;
};
element.addEventListener('mousedown', (e) => startDrag(e.clientX, e.clientY));
document.addEventListener('mousemove', (e) => moveDrag(e.clientX, e.clientY));
document.addEventListener('mouseup', () => isDragging = false);
// 添加触摸事件...
}
使用拖拽 API 实现
HTML5 原生拖拽 API 实现:
draggable.setAttribute('draggable', 'true');
draggable.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', draggable.id);
e.dataTransfer.effectAllowed = 'move';
});
document.addEventListener('dragover', (e) => {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
});
document.addEventListener('drop', (e) => {
e.preventDefault();
const id = e.dataTransfer.getData('text/plain');
const element = document.getElementById(id);
element.style.left = `${e.clientX}px`;
element.style.top = `${e.clientY}px`;
});






