当前位置:首页 > JavaScript

js拖拽实现

2026-04-06 14:15:49JavaScript

基本拖拽实现

HTML结构需要一个可拖拽元素:

<div id="draggable" style="width: 100px; height: 100px; background: #ccc;"></div>

JavaScript实现核心逻辑:

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

拖拽事件优化

添加CSS提升体验:

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

移动端适配

添加触摸事件支持:

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];
  draggable.style.left = `${touch.clientX - offsetX}px`;
  draggable.style.top = `${touch.clientY - offsetY}px`;
});

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

拖拽排序实现

列表项拖拽排序示例:

js拖拽实现

const list = document.getElementById('sortable-list');
let draggedItem = null;

list.addEventListener('dragstart', (e) => {
  draggedItem = e.target;
  setTimeout(() => e.target.classList.add('dragging'), 0);
});

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

list.addEventListener('dragend', (e) => {
  e.target.classList.remove('dragging');
});

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;
    return offset < 0 && offset > closest.offset ? { offset, element: child } : closest;
  }, { offset: Number.NEGATIVE_INFINITY }).element;
}

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

相关文章

js实现分页

js实现分页

分页的基本实现思路 在JavaScript中实现分页功能通常需要结合前端和后端逻辑。前端负责渲染分页控件和处理用户交互,后端负责提供分页数据。 前端分页实现 纯前端分页适用于数据量较小的情况,可以直…

js实现复制

js实现复制

使用document.execCommand方法 在较旧的浏览器中,可以使用document.execCommand('copy')实现复制功能。创建一个临时的textarea或input元素,将需要…

js实现图片放大缩小

js实现图片放大缩小

实现图片放大缩小的基础方法 使用CSS的transform: scale()属性可以快速实现图片的放大缩小效果。通过JavaScript动态修改该属性值: const img = document.…

js 实现vue

js 实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,可以通过数据绑定、响应式系统和虚拟 DOM 来实现。以下是实现 Vue.js 核心功能的简化版本。 数据响应式系…

js实现图表

js实现图表

在JavaScript中实现图表通常使用流行的图表库,以下是几种常见的方法和工具: 使用Chart.js Chart.js是一个简单灵活的库,适合快速生成响应式图表。安装方式包括CDN引入或npm安…

js 实现链表

js 实现链表

链表的基本概念 链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。与数组不同,链表在内存中是非连续存储的,插入和删除操作效率较高。 链表的实现 在 JavaScrip…