当前位置:首页 > JavaScript

js 实现拖拽

2026-04-03 22:23:10JavaScript

基础拖拽实现

使用原生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';
});

拖拽边界限制

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

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

拖拽元素层级管理

确保被拖拽元素始终位于其他元素上方:

js 实现拖拽

draggable.addEventListener('mousedown', () => {
  const maxZ = Math.max(...[...document.querySelectorAll('.draggable')]
    .map(el => parseInt(el.style.zIndex || 0)));
  draggable.style.zIndex = maxZ + 1;
});

拖拽性能优化

使用CSS transform替代top/left属性提升性能:

draggable.style.transform = `translate(${x}px, ${y}px)`;

拖拽事件委托

对于动态生成的多个可拖拽元素,使用事件委托:

js 实现拖拽

document.addEventListener('mousedown', (e) => {
  if (!e.target.classList.contains('draggable')) return;
  // 拖拽逻辑
});

HTML5拖拽API

现代浏览器支持原生拖拽API,适用于更复杂的场景:

draggable.draggable = true;

draggable.addEventListener('dragstart', (e) => {
  e.dataTransfer.setData('text/plain', draggable.id);
});

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

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

触摸屏支持

添加触摸事件支持实现移动端兼容:

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

document.addEventListener('touchmove', (e) => {
  const touch = e.touches[0];
  // 与mousemove相同逻辑
});

拖拽释放回调

添加拖拽结束时的回调处理:

function onDragEnd() {
  // 自定义逻辑
}

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

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

相关文章

js实现图片上传

js实现图片上传

图片上传的基本实现 使用HTML的<input type="file">元素配合JavaScript的File API可以实现图片上传功能。HTML部分需要创建一个文件选择输入框和一个用于…

js实现滚动

js实现滚动

实现滚动效果的方法 在JavaScript中实现滚动效果可以通过多种方式完成,以下是一些常见的方法: 使用window.scrollTo() window.scrollTo()方法可以将页面滚动到指…

js实现搜索

js实现搜索

实现搜索功能的方法 在JavaScript中实现搜索功能可以通过多种方式完成,以下是几种常见的实现方法。 使用数组的filter方法 通过数组的filter方法可以筛选出符合条件的数据项。假设有一个…

js进度条实现

js进度条实现

使用HTML和CSS创建基础结构 在HTML中创建一个容器元素用于显示进度条,通常使用<div>元素。CSS用于设置进度条的样式,包括宽度、高度、颜色和圆角等属性。 <div cl…

js分页实现

js分页实现

分页的基本原理 分页的核心是通过计算当前页码和数据偏移量,从服务器或本地数据中截取对应范围的数据进行展示。通常需要以下参数:当前页码(currentPage)、每页条数(pageSize)、总数据量(…

js实现上传图片

js实现上传图片

使用HTML5的File API实现图片上传 HTML5的File API允许通过JavaScript访问用户选择的文件。需要创建一个文件输入元素,并监听其change事件。 <input t…