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();
相关推荐
胡志辉38 分钟前
深入浅出 call、apply、bind
前端·javascript·后端
十九画生3 小时前
parentID ``` JavaScript 是区分大小写的,所以这两个不是同一个字段。 第二,`parent` 没有声明。 应该先写: `
javascript
怕浪猫4 小时前
Electron 开发实战(十六):总结与展望|生态现状、框架对比、行业趋势与学习指南
前端·javascript·electron
ZengLiangYi5 小时前
批量导入 1000 条对话的性能优化实战
javascript·后端·架构
竹林8185 小时前
用 wagmi v2 + viem 监听合约事件时踩的坑,我花了两天才把"遗漏事件"修好
javascript
小花酱酱5 小时前
QQ群里只有你一个人?邪门歪道破局之路——AstrBot
javascript
bonechips5 小时前
JS 数组指南:从内存原理到二维矩阵
前端·javascript
mONESY5 小时前
前端零基础精讲:Canvas3D、CSS3D、文档流、定位全方位复盘
javascript
竹林81821 小时前
Web3表单签名验证:我用 wagmi 和 ethers 给 DApp 加了一个“免密登录”,踩坑记录全在这了
javascript