当前位置:首页 > JavaScript

js实现弹窗的拖拽效果

2026-04-04 22:07:30JavaScript

实现弹窗拖拽的基本思路

弹窗拖拽功能主要通过监听鼠标事件实现。核心逻辑包括:鼠标按下时记录初始位置,鼠标移动时计算偏移量并更新弹窗位置,鼠标松开时移除事件监听。

HTML结构准备

创建一个基本的弹窗结构,包含标题栏(用于拖拽区域)和内容区域:

<div id="dialog" class="dialog">
  <div class="dialog-header">可拖拽标题</div>
  <div class="dialog-content">弹窗内容...</div>
</div>

CSS样式设置

为弹窗添加基础样式,特别注意设置position: absolute

.dialog {
  position: absolute;
  width: 300px;
  border: 1px solid #ccc;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.dialog-header {
  padding: 10px;
  background: #f5f5f5;
  cursor: move;
  user-select: none;
}

JavaScript实现代码

完整拖拽功能实现:

const dialog = document.getElementById('dialog');
const header = dialog.querySelector('.dialog-header');

let isDragging = false;
let offsetX, offsetY;

header.addEventListener('mousedown', (e) => {
  isDragging = true;
  offsetX = e.clientX - dialog.offsetLeft;
  offsetY = e.clientY - dialog.offsetTop;
  dialog.style.cursor = 'grabbing';
});

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

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

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

边界限制处理

防止弹窗被拖出可视区域:

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

  let left = e.clientX - offsetX;
  let top = e.clientY - offsetY;

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

  dialog.style.left = `${left}px`;
  dialog.style.top = `${top}px`;
});

性能优化版本

使用事件委托和更高效的位置计算:

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

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

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

  function up() {
    document.removeEventListener('mousemove', move);
    document.removeEventListener('mouseup', up);
  }

  document.addEventListener('mousemove', move);
  document.addEventListener('mouseup', up);
});

兼容触摸设备

添加触摸事件支持:

js实现弹窗的拖拽效果

header.addEventListener('touchstart', (e) => {
  const touch = e.touches[0];
  offsetX = touch.clientX - dialog.offsetLeft;
  offsetY = touch.clientY - dialog.offsetTop;
});

document.addEventListener('touchmove', (e) => {
  if (!offsetX && !offsetY) return;
  const touch = e.touches[0];
  dialog.style.left = `${touch.clientX - offsetX}px`;
  dialog.style.top = `${touch.clientY - offsetY}px`;
});

document.addEventListener('touchend', () => {
  offsetX = offsetY = null;
});

标签: 拖拽效果
分享给朋友:

相关文章

vue实现效果

vue实现效果

Vue 实现常见效果的方法 数据绑定与响应式更新 Vue 的核心特性是数据绑定,通过 v-model 实现表单元素与数据的双向绑定。例如输入框与数据的实时同步: <input v-model=…

jquery 效果

jquery 效果

jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画和 Ajax 交互。jQuery 提供了丰富的效果(Effects)功能,可以轻松实现元素的动态显…

vue实现气泡效果

vue实现气泡效果

实现气泡效果的方法 在Vue中实现气泡效果可以通过CSS动画、第三方库或自定义组件完成。以下是几种常见方法: 使用纯CSS动画 通过CSS的@keyframes和transform属性创建气泡上升动…

vue 拖拽排序 实现

vue 拖拽排序 实现

实现拖拽排序的基本思路 在Vue中实现拖拽排序通常需要借助HTML5的拖放API或第三方库如sortablejs、vuedraggable等。以下是两种常见实现方式: 使用HTML5原生拖放API…

vue能实现拖拽

vue能实现拖拽

Vue 实现拖拽的方法 Vue 可以通过多种方式实现拖拽功能,包括原生 HTML5 的拖拽 API、第三方库如 vuedraggable 或自定义指令。以下是几种常见的实现方式: 使用 HTML5…

vue实现元素拖拽

vue实现元素拖拽

Vue 实现元素拖拽的方法 使用 HTML5 原生拖拽 API HTML5 提供了原生拖拽 API,可以通过 draggable 属性结合事件监听实现拖拽功能。 <template>…