js实现窗口拖拽
实现窗口拖拽的基本原理
通过监听鼠标事件(mousedown、mousemove、mouseup)来实现拖拽效果。需要计算鼠标位置与元素位置的偏移量,并在移动过程中更新元素位置。
HTML结构准备
创建一个可拖拽的窗口元素,通常为绝对定位的div:
<div id="draggableWindow" style="position: absolute; width: 300px; height: 200px; background: #eee; cursor: move;">
可拖拽窗口
</div>
JavaScript核心实现
const draggable = document.getElementById('draggableWindow');
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 = 'move';
});
边界限制处理
防止窗口被拖出可视区域:
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`;
});
拖拽性能优化
使用transform替代top/left可以获得更好的性能:
// 修改mousemove事件处理
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
draggable.style.transform = `translate(${e.clientX - offsetX}px, ${e.clientY - offsetY}px)`;
});
// 初始化时需要设置transform-origin
draggable.style.transformOrigin = '0 0';
完整封装示例
function makeDraggable(element) {
let isDragging = false;
let offsetX, offsetY;
element.addEventListener('mousedown', (e) => {
if (e.button !== 0) return; // 仅左键触发
isDragging = true;
offsetX = e.clientX - element.getBoundingClientRect().left;
offsetY = e.clientY - element.getBoundingClientRect().top;
element.style.cursor = 'grabbing';
e.preventDefault(); // 防止文本选中
});
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 - element.offsetWidth));
newY = Math.max(0, Math.min(newY, window.innerHeight - element.offsetHeight));
element.style.left = `${newX}px`;
element.style.top = `${newY}px`;
});
document.addEventListener('mouseup', () => {
isDragging = false;
element.style.cursor = 'move';
});
}
// 使用示例
makeDraggable(document.getElementById('draggableWindow'));
注意事项
- 确保拖拽元素使用
position: absolute或position: fixed - 考虑添加
user-select: none样式防止拖拽时选中文本 - 移动端需要额外处理touch事件
- 复杂场景可考虑使用第三方库如interact.js







