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();
相关推荐
gnip4 小时前
Jst执行上下文栈和变量对象
前端·javascript
拉不动的猪4 小时前
简单回顾下Weakmap在vue中为何不能去作为循环数据源,以及替代方案
前端·javascript·vue.js
How_doyou_do5 小时前
数据传输优化-异步不阻塞处理增强首屏体验
开发语言·前端·javascript
DT——5 小时前
前端登录鉴权详解
前端·javascript
界面开发小八哥6 小时前
数据可视化图表库LightningChart JS v8.0上线:全新图例系统 + 数据集重构
javascript·信息可视化·数据可视化·lightningchart
烛阴6 小时前
【TS 设计模式完全指南】从“入门”到“劝退”,彻底搞懂单例模式
javascript·设计模式·typescript
正义的大古6 小时前
OpenLayers常用控件 -- 章节六:全屏控件教程
前端·javascript·html·openlayers
正义的大古9 小时前
OpenLayers常用控件 -- 章节七:测量工具控件教程
前端·javascript·vue.js·openlayers
雲墨款哥9 小时前
一个前端开发者的救赎之路-JS基础回顾(五)-数组
前端·javascript·面试
朱程9 小时前
深入JS(一):手写 Promise
前端·javascript