Interact.js 一个轻量级拖拽库

Interact.js的核心优势

  1. 轻量级:仅约10KB(gzipped),不依赖其他库
  2. 多点触控支持:完美适配移动设备
  3. 高度可定制:限制区域、惯性效果、吸附功能等
  4. 简洁API:直观的语法,学习曲线平缓
  5. 现代浏览器支持:兼容所有主流浏览器

安装与引入

通过npm安装:

bash 复制代码
npm install interactjs

或使用CDN:

html 复制代码
<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>

基础使用:创建可拖拽元素

html 复制代码
<div id="draggable" class="box">
  拖拽我
</div>
javascript 复制代码
interact('#draggable').draggable({
  inertia: true, // 启用惯性效果
  autoScroll: true,
  listeners: {
    move: dragMoveListener
  }
});

function dragMoveListener(event) {
  const target = event.target;
  const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
  const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

  target.style.transform = `translate(${x}px, ${y}px)`;
  target.setAttribute('data-x', x);
  target.setAttribute('data-y', y);
}

核心API详解

1. 拖拽功能(Draggable)

javascript 复制代码
interact('.draggable').draggable({
  // 限制在父元素内移动
  modifiers: [
    interact.modifiers.restrictRect({
      restriction: 'parent',
      endOnly: true
    })
  ],
  // 开始拖拽时添加样式
  onstart: function(event) {
    event.target.classList.add('dragging');
  },
  // 拖拽结束
  onend: function(event) {
    event.target.classList.remove('dragging');
  }
});

2. 调整大小(Resizable)

javascript 复制代码
interact('.resizable').resizable({
  edges: { left: true, right: true, bottom: true, top: true },
  // 限制最小尺寸
  modifiers: [
    interact.modifiers.restrictSize({
      min: { width: 100, height: 100 }
    })
  ],
  listeners: {
    move: function(event) {
      const target = event.target;
      let x = parseFloat(target.getAttribute('data-x')) || 0;
      let y = parseFloat(target.getAttribute('data-y')) || 0;
      
      // 更新元素尺寸
      target.style.width = event.rect.width + 'px';
      target.style.height = event.rect.height + 'px';
      
      // 调整位置(当从左侧或顶部调整时)
      x += event.deltaRect.left;
      y += event.deltaRect.top;
      
      target.style.transform = `translate(${x}px, ${y}px)`;
      target.setAttribute('data-x', x);
      target.setAttribute('data-y', y);
    }
  }
});

3. 放置区域(Dropzone)

javascript 复制代码
interact('.dropzone').dropzone({
  accept: '.draggable', // 只接受特定元素
  overlap: 0.5, // 至少重叠50%才算放置有效
  
  ondropactivate: function(event) {
    event.target.classList.add('drop-active');
  },
  ondragenter: function(event) {
    event.target.classList.add('drop-target');
  },
  ondragleave: function(event) {
    event.target.classList.remove('drop-target');
  },
  ondrop: function(event) {
    // 处理放置逻辑
    event.target.appendChild(event.relatedTarget);
  },
  ondropdeactivate: function(event) {
    event.target.classList.remove('drop-active');
    event.target.classList.remove('drop-target');
  }
});

高级功能

1. 限制与约束

javascript 复制代码
// 限制在特定区域内移动
interact.modifiers.restrict({
  restriction: document.getElementById('boundary'),
  elementRect: { top: 0, left: 0, bottom: 1, right: 1 },
  endOnly: true
})

// 吸附到网格
interact.modifiers.snap({
  targets: [
    interact.snappers.grid({ x: 20, y: 20 })
  ],
  range: Infinity,
  relativePoints: [ { x: 0, y: 0 } ]
})

2. 手势支持

javascript 复制代码
interact('.gesture').gesturable({
  listeners: {
    move: function(event) {
      const target = event.target;
      const scale = parseFloat(target.getAttribute('data-scale')) || 1;
      const rotation = parseFloat(target.getAttribute('data-rotation')) || 0;
      
      target.style.transform = 
        `rotate(${rotation + event.da}deg)
         scale(${scale * (1 + event.ds)})`;
      
      target.setAttribute('data-scale', scale * (1 + event.ds));
      target.setAttribute('data-rotation', rotation + event.da);
    }
  }
});

性能优化技巧

  1. 使用CSS变换而非定位:优先使用transform而非top/left
  2. 事件委托:对动态元素使用事件委托
  3. 适当限制事件频率:使用requestAnimationFrame节流事件
  4. 避免复杂选择器:在拖拽元素上使用简单类名
  5. 及时销毁实例 :移除元素时调用unset()方法
javascript 复制代码
// 销毁实例
const draggable = interact('#element');
// 移除拖拽功能
draggable.unset();
相关推荐
Async Cipher16 分钟前
JSON-LD 的格式
前端·javascript
Dontla17 分钟前
Next.js项目演示(从零创建Next.js项目)Next.js入门实战
开发语言·javascript·ecmascript
How_doyou_do1 小时前
样式冲突修复组件
前端·javascript·html
**之火2 小时前
中止 Web 请求新方式 - AbortController API
开发语言·前端·javascript
知识分享小能手2 小时前
微信小程序入门学习教程,从入门到精通,微信小程序页面交互 —— 知识点详解与案例实现(3)
前端·javascript·学习·react.js·微信小程序·小程序·交互
m0_616188492 小时前
CSS中的伪类和伪元素
前端·javascript·css
快乐就好ya2 小时前
React基础到进阶
前端·javascript·react.js
悠哉摸鱼大王3 小时前
多模态场景下tts功能实现
前端·javascript
初出茅庐的3 小时前
hooks&&状态管理&&业务管理
前端·javascript·vue.js
aricvvang3 小时前
一行 Promise.all 争议:数据库查询并行真的没用?我和同事吵赢了!!!
javascript·后端·node.js