当前位置:首页 > JavaScript

js实现 拖动

2026-02-28 21:51:08JavaScript

实现基本拖动功能

使用JavaScript实现拖动功能需要监听三个主要事件:mousedownmousemovemouseup。以下是基础实现代码:

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';
});

添加边界限制

为防止元素被拖出可视区域,可以添加边界检查:

js实现 拖动

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

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

  // 限制在窗口范围内
  x = Math.max(0, Math.min(x, window.innerWidth - draggable.offsetWidth));
  y = Math.max(0, Math.min(y, window.innerHeight - draggable.offsetHeight));

  draggable.style.left = `${x}px`;
  draggable.style.top = `${y}px`;
});

支持触摸设备

为支持移动设备触摸操作,需要添加触摸事件处理:

draggable.addEventListener('touchstart', (e) => {
  isDragging = true;
  const touch = e.touches[0];
  offsetX = touch.clientX - draggable.getBoundingClientRect().left;
  offsetY = touch.clientY - draggable.getBoundingClientRect().top;
});

document.addEventListener('touchmove', (e) => {
  if (!isDragging) return;
  const touch = e.touches[0];
  let x = touch.clientX - offsetX;
  let y = touch.clientY - offsetY;

  x = Math.max(0, Math.min(x, window.innerWidth - draggable.offsetWidth));
  y = Math.max(0, Math.min(y, window.innerHeight - draggable.offsetHeight));

  draggable.style.left = `${x}px`;
  draggable.style.top = `${y}px`;
});

document.addEventListener('touchend', () => {
  isDragging = false;
});

使用CSS优化拖动体验

添加CSS样式提升拖动时的视觉效果:

js实现 拖动

#draggable {
  position: absolute;
  cursor: grab;
  user-select: none;
  touch-action: none;
}

#draggable:active {
  cursor: grabbing;
}

实现拖动排序功能

扩展实现拖动排序功能,需要跟踪元素位置变化:

const container = document.getElementById('container');
const items = Array.from(container.children);
let draggedItem = null;

items.forEach(item => {
  item.addEventListener('dragstart', () => {
    draggedItem = item;
    setTimeout(() => item.classList.add('dragging'), 0);
  });

  item.addEventListener('dragend', () => {
    item.classList.remove('dragging');
    draggedItem = null;
  });
});

container.addEventListener('dragover', e => {
  e.preventDefault();
  const afterElement = getDragAfterElement(container, e.clientY);
  if (afterElement) {
    container.insertBefore(draggedItem, afterElement);
  } else {
    container.appendChild(draggedItem);
  }
});

function getDragAfterElement(container, y) {
  const elements = [...container.querySelectorAll('.item:not(.dragging)')];

  return elements.reduce((closest, child) => {
    const box = child.getBoundingClientRect();
    const offset = y - box.top - box.height / 2;
    if (offset < 0 && offset > closest.offset) {
      return { offset, element: child };
    } else {
      return closest;
    }
  }, { offset: Number.NEGATIVE_INFINITY }).element;
}

使用HTML5 Drag API

利用原生HTML5拖放API实现更标准的拖动:

<div id="container">
  <div class="item" draggable="true">Item 1</div>
  <div class="item" draggable="true">Item 2</div>
</div>
document.querySelectorAll('.item').forEach(item => {
  item.addEventListener('dragstart', () => {
    item.classList.add('dragging');
  });

  item.addEventListener('dragend', () => {
    item.classList.remove('dragging');
  });
});

container.addEventListener('dragover', e => {
  e.preventDefault();
  const afterElement = getDragAfterElement(container, e.clientY);
  const dragging = document.querySelector('.dragging');
  if (afterElement) {
    container.insertBefore(dragging, afterElement);
  } else {
    container.appendChild(dragging);
  }
});

标签: 拖动js
分享给朋友:

相关文章

js实现倒计时

js实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时功能可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是几种常见的实现方式: 使用 setInterva…

js 实现倒计时

js 实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是两种常见实现方式。 使用 setInterval 实…

js实现百叶窗

js实现百叶窗

使用CSS和JavaScript实现百叶窗效果 通过CSS动画和JavaScript事件监听可以实现百叶窗效果。核心思路是将内容区域分割为多个条状元素,通过控制它们的展开/折叠状态来模拟百叶窗。 &…

js实现游标

js实现游标

使用JavaScript实现游标 在JavaScript中,可以通过操作DOM元素的cursor样式属性来实现自定义游标效果。以下是几种常见的实现方法: 修改默认鼠标指针样式 通过CSS的curso…

js实现授权

js实现授权

授权流程设计 授权流程通常涉及前端与后端的交互,常见方案包括OAuth2.0、JWT等。以JWT为例的典型流程: 用户提交凭证(如用户名密码)到认证服务 服务端验证通过后生成包含用户信息的J…

js实现 功能

js实现 功能

在 JavaScript 中实现功能通常涉及多个关键步骤,具体取决于功能需求。以下是常见功能的实现方法和示例: 基本功能实现 使用函数封装逻辑是最直接的方式。例如,实现一个计算两数之和的函数: f…