npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

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 - 免费用于个人和商业项目