js 实现拖拽
基础拖拽实现
使用原生JavaScript实现拖拽功能需要监听三个主要事件: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('mousedown', () => {
const maxZ = Math.max(...[...document.querySelectorAll('.draggable')]
.map(el => parseInt(el.style.zIndex || 0)));
draggable.style.zIndex = maxZ + 1;
});
拖拽性能优化
使用CSS transform替代top/left属性提升性能:
draggable.style.transform = `translate(${x}px, ${y}px)`;
拖拽事件委托
对于动态生成的多个可拖拽元素,使用事件委托:
document.addEventListener('mousedown', (e) => {
if (!e.target.classList.contains('draggable')) return;
// 拖拽逻辑
});
HTML5拖拽API
现代浏览器支持原生拖拽API,适用于更复杂的场景:
draggable.draggable = true;
draggable.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', draggable.id);
});
document.addEventListener('dragover', (e) => {
e.preventDefault();
});
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`;
});
触摸屏支持
添加触摸事件支持实现移动端兼容:
draggable.addEventListener('touchstart', (e) => {
const touch = e.touches[0];
offsetX = touch.clientX - draggable.getBoundingClientRect().left;
offsetY = touch.clientY - draggable.getBoundingClientRect().top;
});
document.addEventListener('touchmove', (e) => {
const touch = e.touches[0];
// 与mousemove相同逻辑
});
拖拽释放回调
添加拖拽结束时的回调处理:

function onDragEnd() {
// 自定义逻辑
}
document.addEventListener('mouseup', () => {
isDragging = false;
onDragEnd();
});






