ele-drag
v1.0.1
Published
一个简单易用的js拖动库
Readme
Dragable.js - 轻量级跨平台拖动库
简介
Dragable.js 是一个简单易用的 JavaScript 拖动库,支持移动端和电脑端触摸/鼠标事件。它通过扩展 HTMLElement 原型提供了直观的 API,无需复杂配置即可实现元素的拖动功能。
安装与引入
CDN 引入
<!-- 通过 unpkg 引入 -->
<script src="https://unpkg.com/dragable-js"></script>
<!-- 或通过 jsdelivr 引入 -->
<script src="https://cdn.jsdelivr.net/npm/dragable-js"></script>npm 安装
npm install dragable-js然后通过模块系统引入:
import 'dragable-js'; // 全局注册
// 或
import { enableDrag, disableDrag } from 'dragable-js'; // 按需引入基本使用
启用拖动
// 获取元素
const element = document.getElementById('drag-me');
// 启用拖动
element.enableDrag();禁用拖动
// 禁用拖动
element.disableDrag();高级配置
拖动限制
你可以通过 CSS 或 JavaScript 限制拖动范围:
#drag-me {
position: absolute;
/* 限制在父容器内拖动 */
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
width: 100px;
height: 100px;
}自定义拖动句柄
如果你想只在特定子元素上触发拖动:
const handle = element.querySelector('.drag-handle');
handle.addEventListener('mousedown', (e) => {
e.preventDefault();
element.enableDrag();
});
document.addEventListener('mouseup', () => {
element.disableDrag();
});事件系统
Dragable.js 提供了完整的事件生命周期:
dragstart
拖动开始时触发
element.addEventListener('dragstart', (e) => {
console.log('开始拖动', e.detail);
// e.detail 包含 { x, y } 起始坐标
});dragmove
拖动过程中持续触发
element.addEventListener('dragmove', (e) => {
console.log('拖动中', e.detail);
// e.detail 包含 { x, y, left, top } 当前坐标和位置
});dragend
拖动结束时触发
element.addEventListener('dragend', () => {
console.log('拖动结束');
});样式定制
当元素被拖动时,会自动添加 dragging 类,你可以利用这个类添加视觉效果:
.dragging {
opacity: 0.8;
cursor: grabbing;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
transition: none; /* 拖动时禁用过渡效果 */
}
/* 拖动句柄样式 */
.drag-handle {
cursor: grab;
}
.drag-handle:active {
cursor: grabbing;
}最佳实践
1. 性能优化
对于大量可拖动元素,建议:
// 批量启用拖动
document.querySelectorAll('.draggable-item').forEach(item => {
item.enableDrag();
});
// 使用事件委托处理拖动事件
document.addEventListener('dragmove', (e) => {
if (e.target.classList.contains('important-item')) {
// 特殊处理
}
});2. 移动端适配
确保添加以下 meta 标签防止浏览器默认行为:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">3. 无障碍访问
为可拖动元素添加 ARIA 属性:
<div id="drag-me" aria-grabbed="false" tabindex="0">
可拖动元素
</div>并通过 JavaScript 更新状态:
element.addEventListener('dragstart', () => {
element.setAttribute('aria-grabbed', 'true');
});
element.addEventListener('dragend', () => {
element.setAttribute('aria-grabbed', 'false');
});API 参考
HTMLElement 原型方法
| 方法 | 描述 | 示例 |
|------|------|------|
| enableDrag() | 启用元素拖动功能 | element.enableDrag() |
| disableDrag() | 禁用元素拖动功能 | element.disableDrag() |
自定义事件
| 事件 | 触发时机 | 事件详情 |
|------|----------|----------|
| dragstart | 拖动开始时触发 | { x, y } 起始坐标 |
| dragmove | 拖动过程中持续触发 | { x, y, left, top } 当前坐标和位置 |
| dragend | 拖动结束时触发 | 无 |
常见问题
Q: 拖动时页面也跟着滚动怎么办?
A: 确保在可滚动容器中使用,或添加以下 CSS:
body {
overflow: hidden;
}Q: 如何限制拖动范围?
A: 在 dragmove 事件中检查并修正位置:
element.addEventListener('dragmove', (e) => {
const { left, top } = e.detail;
const maxX = window.innerWidth - element.offsetWidth;
const maxY = window.innerHeight - element.offsetHeight;
element.style.left = `${Math.max(0, Math.min(left, maxX))}px`;
element.style.top = `${Math.max(0, Math.min(top, maxY))}px`;
});Q: 如何实现磁贴吸附效果?
A: 在 dragend 事件中处理:
element.addEventListener('dragend', () => {
const rect = element.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
// 找到最近的吸附点
const snapPoints = [...]; // 你的吸附点数组
const closest = snapPoints.reduce((prev, curr) => {
const prevDist = Math.hypot(prev.x - centerX, prev.y - centerY);
const currDist = Math.hypot(curr.x - centerX, curr.y - centerY);
return currDist < prevDist ? curr : prev;
});
// 动画到吸附点
element.style.transition = 'all 0.3s ease';
element.style.left = `${closest.x - rect.width / 2}px`;
element.style.top = `${closest.y - rect.height / 2}px`;
setTimeout(() => {
element.style.transition = '';
}, 300);
});版本更新
v1.0.1
- 修复了移动端多点触控的问题
- 提高了事件处理的性能
v1.0.0
- 初始发布版本
- 支持基础拖动功能
- 跨平台触摸/鼠标事件支持
许可证
MIT License - 免费用于个人和商业项目
