当前位置:首页 > 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实现分页

实现分页的基本思路 分页功能通常需要处理数据分割、页码生成和用户交互。核心逻辑包括计算总页数、根据当前页截取数据、渲染页码按钮等。 前端分页实现(静态数据) 假设已有全部数据,仅需前端分页展示:…

js实现倒计时

js实现倒计时

使用 setInterval 实现倒计时 通过 setInterval 定时器每秒更新剩余时间,适用于简单倒计时场景。 function countdown(seconds, callback)…

js实现继承

js实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Paren…

js实现图片轮播

js实现图片轮播

实现基础图片轮播 使用HTML、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS设置样式和动画效果,JavaScript处理轮播逻辑。 <div c…

jquery.js

jquery.js

jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画设计和 Ajax 交互等操作。以下是关于 jQuery.js 的核心信息和使用方法: 获取…

js实现vr

js实现vr

使用WebXR API实现VR体验 WebXR是浏览器中实现VR和AR体验的标准API,它取代了早期的WebVR。现代浏览器如Chrome、Edge和Firefox已支持WebXR。 // 初始化W…