当前位置:首页 > JavaScript

js实现拖动元素

2026-02-03 02:42:51JavaScript

实现元素拖动的基本原理

通过监听鼠标事件(mousedownmousemovemouseup)实现元素拖动。核心逻辑是计算鼠标移动距离并更新元素位置。

基本实现代码

const draggableElement = document.getElementById('draggable');

let isDragging = false;
let offsetX, offsetY;

draggableElement.addEventListener('mousedown', (e) => {
  isDragging = true;
  offsetX = e.clientX - draggableElement.getBoundingClientRect().left;
  offsetY = e.clientY - draggableElement.getBoundingClientRect().top;

  draggableElement.style.cursor = 'grabbing';
});

document.addEventListener('mousemove', (e) => {
  if (!isDragging) return;

  draggableElement.style.left = `${e.clientX - offsetX}px`;
  draggableElement.style.top = `${e.clientY - offsetY}px`;
});

document.addEventListener('mouseup', () => {
  isDragging = false;
  draggableElement.style.cursor = 'grab';
});

CSS 初始设置

确保元素可定位并设置初始样式:

js实现拖动元素

#draggable {
  position: absolute;
  cursor: grab;
  user-select: none; /* 防止拖动时选中文本 */
}

优化版本(边界限制)

防止元素被拖出视窗:

js实现拖动元素

document.addEventListener('mousemove', (e) => {
  if (!isDragging) return;

  const x = e.clientX - offsetX;
  const y = e.clientY - offsetY;

  // 视窗边界检测
  const maxX = window.innerWidth - draggableElement.offsetWidth;
  const maxY = window.innerHeight - draggableElement.offsetHeight;

  draggableElement.style.left = `${Math.max(0, Math.min(x, maxX))}px`;
  draggableElement.style.top = `${Math.max(0, Math.min(y, maxY))}px`;
});

使用事件委托实现多元素拖动

document.addEventListener('mousedown', (e) => {
  if (!e.target.classList.contains('draggable')) return;

  const element = e.target;
  const rect = element.getBoundingClientRect();
  const offsetX = e.clientX - rect.left;
  const offsetY = e.clientY - rect.top;

  function moveHandler(e) {
    element.style.left = `${e.clientX - offsetX}px`;
    element.style.top = `${e.clientY - offsetY}px`;
  }

  function upHandler() {
    document.removeEventListener('mousemove', moveHandler);
    document.removeEventListener('mouseup', upHandler);
  }

  document.addEventListener('mousemove', moveHandler);
  document.addEventListener('mouseup', upHandler);
});

使用 HTML5 Drag API 实现

更简单的原生拖动方案:

document.querySelectorAll('.draggable').forEach(el => {
  el.draggable = true;

  el.addEventListener('dragstart', (e) => {
    e.dataTransfer.setData('text/plain', e.target.id);
    e.target.classList.add('dragging');
  });
});

document.addEventListener('dragover', (e) => {
  e.preventDefault();
});

document.addEventListener('drop', (e) => {
  e.preventDefault();
  const id = e.dataTransfer.getData('text/plain');
  const draggable = document.getElementById(id);
  draggable.style.left = `${e.clientX}px`;
  draggable.style.top = `${e.clientY}px`;
  draggable.classList.remove('dragging');
});

性能优化建议

对于频繁触发的 mousemove 事件,可以使用节流(throttling)技术:

function throttle(fn, delay) {
  let lastCall = 0;
  return function(...args) {
    const now = new Date().getTime();
    if (now - lastCall < delay) return;
    lastCall = now;
    return fn(...args);
  };
}

document.addEventListener('mousemove', throttle((e) => {
  // 拖动逻辑
}, 16)); // 约60fps

标签: 拖动元素
分享给朋友:

相关文章

vue实现拖动刻度

vue实现拖动刻度

实现拖动刻度功能 在Vue中实现拖动刻度功能可以通过结合原生HTML5的拖拽API和Vue的数据绑定特性来完成。以下是一个完整的实现方案: 基本实现思路 创建一个可拖动的滑块元素 监听鼠标事件处理拖…

vue实现元素共享

vue实现元素共享

Vue 实现元素共享的方法 在 Vue 中实现元素共享通常涉及组件间的数据传递或状态管理。以下是几种常见的方法: 使用 Props 和 Events 父组件通过 props 向子组件传递数据,子组件…

vue实现元素无限滚动

vue实现元素无限滚动

无限滚动的实现方法 使用Vue实现无限滚动可以通过监听滚动事件或使用现成的库来完成。以下是几种常见的实现方式: 使用Intersection Observer API Intersection Ob…

react如何获得所有元素

react如何获得所有元素

在 React 中获取所有元素可以通过多种方式实现,具体取决于场景和需求。以下是几种常见的方法: 使用 ref 获取 DOM 元素 通过 ref 可以访问组件的 DOM 节点或 React 元素。结…

react前端如何审查元素

react前端如何审查元素

审查 React 元素的方法 浏览器开发者工具 在 Chrome 或 Firefox 中右键点击页面元素,选择“检查”或“审查元素”,打开开发者工具。React 组件会以普通 DOM 形式展示,但可通…

react里面如何获取元素

react里面如何获取元素

在React中获取DOM元素有多种方法,以下是常见的几种方式: 使用ref属性 通过useRef钩子或createRef方法创建引用,绑定到目标元素的ref属性上。适用于函数组件和类组件。 imp…