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

js实现弹窗的拖拽效果

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

边界限制处理

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

js实现弹窗的拖拽效果

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

兼容触摸设备

添加触摸事件支持:

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

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

相关文章

js 实现拖拽

js 实现拖拽

实现拖拽的基本步骤 在JavaScript中实现拖拽功能需要监听几个关键事件:mousedown、mousemove和mouseup。以下是实现的基本逻辑。 监听目标元素的mousedown事件,记…

vue实现面板拖拽

vue实现面板拖拽

Vue 实现面板拖拽的方法 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 draggable 属性和相关事件实现拖拽功能。 在 Vue 模板中为元素添加 dra…

vue实现盒子拖拽

vue实现盒子拖拽

实现盒子拖拽的基本思路 在Vue中实现盒子拖拽功能,可以通过监听鼠标事件(mousedown、mousemove、mouseup)来实现。核心逻辑是记录拖拽起始位置,计算位移差值,并更新盒子的位置。…

vue 实现分页效果

vue 实现分页效果

使用 Element UI 实现分页 Element UI 提供了现成的分页组件 el-pagination,适合快速集成到 Vue 项目中。 安装 Element UI: npm install…

vue实现开关效果

vue实现开关效果

使用Vue实现开关效果 使用v-model绑定数据 通过v-model绑定一个布尔值来控制开关状态。当用户点击开关时,布尔值会自动更新。 <template> <div cla…

vue实现图表拖拽

vue实现图表拖拽

Vue 实现图表拖拽功能 在 Vue 中实现图表拖拽功能,可以通过结合第三方图表库(如 ECharts、Chart.js)和拖拽库(如 interact.js、draggable)来完成。以下是几种常…