js实现拖拽插件
实现拖拽插件的基本思路
拖拽功能的核心是监听鼠标事件(mousedown、mousemove、mouseup),通过计算坐标差值实现元素移动。以下是一个基础实现方案:
class Draggable {
constructor(element) {
this.element = element;
this.isDragging = false;
this.offsetX = 0;
this.offsetY = 0;
this.init();
}
init() {
this.element.style.position = 'absolute';
this.element.addEventListener('mousedown', this.onMouseDown.bind(this));
document.addEventListener('mousemove', this.onMouseMove.bind(this));
document.addEventListener('mouseup', this.onMouseUp.bind(this));
}
onMouseDown(e) {
this.isDragging = true;
this.offsetX = e.clientX - this.element.getBoundingClientRect().left;
this.offsetY = e.clientY - this.element.getBoundingClientRect().top;
}
onMouseMove(e) {
if (!this.isDragging) return;
this.element.style.left = `${e.clientX - this.offsetX}px`;
this.element.style.top = `${e.clientY - this.offsetY}px`;
}
onMouseUp() {
this.isDragging = false;
}
}
进阶功能扩展
边界限制
添加边界检测防止元素被拖出可视区域:
onMouseMove(e) {
if (!this.isDragging) return;
let x = e.clientX - this.offsetX;
let y = e.clientY - this.offsetY;
// 限制在窗口范围内
x = Math.max(0, Math.min(x, window.innerWidth - this.element.offsetWidth));
y = Math.max(0, Math.min(y, window.innerHeight - this.element.offsetHeight));
this.element.style.left = `${x}px`;
this.element.style.top = `${y}px`;
}
拖拽手柄
指定特定元素作为拖拽手柄:
constructor(element, handleSelector) {
this.handle = handleSelector
? element.querySelector(handleSelector)
: element;
// 其余初始化代码...
}
init() {
this.handle.addEventListener('mousedown', this.onMouseDown.bind(this));
// 其余事件监听...
}
事件回调支持
添加自定义事件回调提升插件灵活性:
constructor(element, options = {}) {
this.onDragStart = options.onDragStart || (() => {});
this.onDragEnd = options.onDragEnd || (() => {});
this.onDrag = options.onDrag || (() => {});
}
onMouseDown(e) {
this.onDragStart(e);
// 其余逻辑...
}
onMouseMove(e) {
if (!this.isDragging) return;
this.onDrag(e);
// 其余逻辑...
}
onMouseUp(e) {
this.onDragEnd(e);
// 其余逻辑...
}
使用示例
<div id="drag-box" style="width: 100px; height: 100px; background: red;"></div>
<script>
new Draggable(document.getElementById('drag-box'), {
onDragStart: (e) => console.log('拖拽开始'),
onDrag: (e) => console.log('拖拽中', e.clientX, e.clientY),
onDragEnd: (e) => console.log('拖拽结束')
});
</script>
注意事项
- 确保目标元素具有
position: absolute或position: relative样式 - 移动端需要额外处理
touchstart/touchmove/touchend事件 - 性能优化:高频的
mousemove事件可使用requestAnimationFrame节流







