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();
相关推荐
菜鸟‍17 小时前
【前端学习】阿里前端面试题
前端·javascript·学习
用户479492835691518 小时前
告别span嵌套地狱:CSS Highlights API重新定义语法高亮
前端·javascript·css
九章云极AladdinEdu20 小时前
项目分享|告别枯燥命令行,构建终端用户界面的 TypeScript 库
javascript·ui·typescript
带着梦想扬帆启航20 小时前
UniApp 多个异步开关控制教程
前端·javascript·uni-app
小高00721 小时前
JavaScript 内存管理是如何工作的?
前端·javascript
是大林的林吖21 小时前
解决 elementui el-cascader组件懒加载时存在选中状态丢失的问题?
前端·javascript·elementui
默 语21 小时前
Electron 应用中的系统检测方案对比与鸿蒙适配实践
javascript·electron·harmonyos·gwo
Zyx200721 小时前
JavaScript 异步编程深度解析(上):单线程、事件循环与异步的本质
javascript
晴殇i21 小时前
前端代码规范体系建设与团队落地实践
前端·javascript·面试