js实现div拖拽
实现div拖拽的基本思路
通过监听鼠标事件(mousedown、mousemove、mouseup)来实现拖拽效果。记录鼠标按下时的初始位置和元素初始位置,计算移动距离并更新元素位置。
基本实现代码
const draggable = document.getElementById('draggable');
let isDragging = false;
let offsetX, offsetY;
draggable.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - draggable.offsetLeft;
offsetY = e.clientY - draggable.offsetTop;
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';
});
CSS样式要求
确保拖拽元素使用绝对定位:
#draggable {
position: absolute;
cursor: grab;
user-select: none; /* 防止拖动时选中文本 */
}
边界限制实现
防止元素被拖出可视区域:
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
let newX = e.clientX - offsetX;
let newY = e.clientY - offsetY;
// 限制在窗口范围内
newX = Math.max(0, Math.min(newX, window.innerWidth - draggable.offsetWidth));
newY = Math.max(0, Math.min(newY, window.innerHeight - draggable.offsetHeight));
draggable.style.left = `${newX}px`;
draggable.style.top = `${newY}px`;
});
拖拽手柄实现
如果只需要特定区域触发拖拽:
const handle = document.querySelector('.drag-handle');
handle.addEventListener('mousedown', (e) => {
// 拖拽逻辑相同
});
使用HTML5拖拽API
另一种实现方式:
draggable.draggable = true;
draggable.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', draggable.id);
e.dataTransfer.effectAllowed = 'move';
});
document.addEventListener('dragover', (e) => {
e.preventDefault();
});
document.addEventListener('drop', (e) => {
e.preventDefault();
const id = e.dataTransfer.getData('text/plain');
const el = document.getElementById(id);
el.style.left = `${e.clientX}px`;
el.style.top = `${e.clientY}px`;
});
性能优化建议
对于频繁触发的mousemove事件,可以使用requestAnimationFrame进行节流:

let animationId;
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
cancelAnimationFrame(animationId);
animationId = requestAnimationFrame(() => {
// 更新位置逻辑
});
});






