>> 知识

记录一个非常实用的前端拖拽插件interact.js(JS前端开发)


分类:默认 作者:myerob 标签:前端 拖拽 插件 interact JS 开发 阅读:15 收藏
导读:
本文记录了一个非常实用的前端拖拽插件interact.js,JS拖放、调整大小和多点触控手势,适用于多数浏览器(包含IE9+)。interact.js采用了一种与大多数拖放库略有不同的方法。为了尽可能…

本文记录了一个非常实用的前端拖拽插件interact.js,JS拖放、调整大小和多点触控手势,适用于多数浏览器。interact.js采用了一种与大多数拖放库略有不同的方法。为了尽可能多地提供控制,它尝试提供一个简单、灵活的API,该API为您提供移动元素所需的所有拖拽API。

1、你可以通过两种方式获取该插件:

(1)通过npm工具安装

npm install interactjs

(2)CDN引入

<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>

或者

<script src="https://unpkg.com/interactjs/dist/interact.min.js"></script>

2、使用方法

  1. 先引安装或入插件,见上文所示。

。。创建可交互的元素,拖拽是interactive.js提供的最简单的动作。要使元素可拖放,请创建一个与您想要的目标可交互的元素,然后使用您需要的选项调用拖放方法。

<div class="draggable"> Draggable Element </div>
const position = { x: 0, y: 0 }

interact('.draggable').draggable({
  listeners: {
    start (event) {
      console.log(event.type, event.target)
    },
    move (event) {
      position.x += event.dx
      position.y += event.dy

      event.target.style.transform =
        `translate(${position.x}px, ${position.y}px)`
    },
  }
})

特别说明:dragmove还有dragEnter和dragLeave 两个事件。

3.调整大小

Resize事件有rect和deltaRect属性。rect在每个resizemove事件上更新,deltaRect中的值反映了更改。在resizestart中,rect将与interactable返回的rect相同。getrect(element)和deltaRect将具有全零属性。

interact('.resizable')
  .resizable({
    edges: { top: true, left: true, bottom: true, right: true },
    listeners: {
      move: function (event) {
        let { x, y } = event.target.dataset

        x = (parseFloat(x) || 0) + event.deltaRect.left
        y = (parseFloat(y) || 0) + event.deltaRect.top

        Object.assign(event.target.style, {
          width: `${event.rect.width}px`,
          height: `${event.rect.height}px`,
          transform: `translate(${x}px, ${y}px)`
        })

        Object.assign(event.target.dataset, { x, y })
      }
    }
  })

4.拖动和放置

dropzone定义了可拖放目标的元素,以及哪些元素可以被接受。和拖放事件一样,拖放事件不会修改DOM来重新创建父元素。如果需要,您必须在自己的事件监听器中这样做。

DropzoneEvents代码示例:

interact(dropTarget)
  .dropzone({
    ondrop: function (event) {
      alert(event.relatedTarget.id
            + ' was dropped into '
            + event.target.id)
    }
  })
  .on('dropactivate', function (event) {
    event.target.classList.add('drop-activated')
  })

accept:accept选项是一个CSS选择器或元素,它必须匹配被拖动的元素,以便触发拖放事件。

interact('.dropzone').dropzone({
  accept: '.drag0, .drag1',
});

checker:checker选项是一个函数,你可以设置它来另外检查一个拖动的元素是否可以拖放到dropzone中。

interact(target).dropzone({
  checker: function (
    dragEvent,         // related dragmove or dragend
    event,             // Touch, Pointer or Mouse Event
    dropped,           // bool default checker result
    dropzone,          // dropzone Interactable
    dropzoneElement,   // dropzone element
    draggable,         // draggable Interactable
    draggableElement   // draggable element
  ) {

    // only allow drops into empty dropzone elements
    return dropped && !dropElement.hasChildNodes();
  }
});

多点触摸旋转(仅触摸屏):当两个手指移动时,手势事件被触发。在手势事件中,页面和客户端坐标是触摸坐标的平均值,速度是根据这些平均值计算的。

var angle = 0

interact('#rotate-area').gesturable({
  listeners: {
    move (event) {
      var arrow = document.getElementById('arrow')

      angle += event.da

      arrow.style.webkitTransform =
      arrow.style.transform =
        'rotate(' + angle + 'deg)'

      document.getElementById('angle-info').textContent =
        angle.toFixed(2) + '\u00b0'
    }
  }
})

特别记住:使用CSStouch-action:none来防止当用户用触摸指针拖动时浏览器进行平移,user-select:none来禁用文本选择。

双指放大(仅触摸屏,和旋转方法一样)

var angleScale = {
  angle: 0,
  scale: 1
}
var gestureArea = document.getElementById('gesture-area')
var scaleElement = document.getElementById('scale-element')
var resetTimeout

interact(gestureArea)
  .gesturable({
    listeners: {
      start (event) {
        angleScale.angle -= event.angle

        clearTimeout(resetTimeout)
        scaleElement.classList.remove('reset')
      },
      move (event) {
        // document.body.appendChild(new Text(event.scale))
        var currentAngle = event.angle + angleScale.angle
        var currentScale = event.scale * angleScale.scale

        scaleElement.style.webkitTransform =
        scaleElement.style.transform =
          'rotate(' + currentAngle + 'deg)' + 'scale(' + currentScale + ')'

        // uses the dragMoveListener from the draggable demo above
        dragMoveListener(event)
      },
      end (event) {
        angleScale.angle = angleScale.angle + event.angle
        angleScale.scale = angleScale.scale * event.scale

        resetTimeout = setTimeout(reset, 1000)
        scaleElement.classList.add('reset')
      }
    }
  })
  .draggable({
    listeners: { move: dragMoveListener }
  })

function reset () {
  scaleElement.style.webkitTransform =
    scaleElement.style.transform =
    'scale(1)'

  angleScale.angle = 0
  angleScale.scale = 1
}

手指事件:单击双击长按(Tap,doubletapandhold)

interact('.tap-target')
  .on('tap', function (event) {
    event.currentTarget.classList.toggle('switch-bg')
    event.preventDefault()
  })
  .on('doubletap', function (event) {
    event.currentTarget.classList.toggle('large')
    event.currentTarget.classList.remove('rotate')
    event.preventDefault()
  })
  .on('hold', function (event) {
    event.currentTarget.classList.toggle('rotate')
    event.currentTarget.classList.remove('large')
  })

文档地址:https://interactjs.io/docs/events#pointer-events

 


相关推荐