easy-drag——轻松帮你实现丝滑的拖拽效果
作为一名前端打工人,你大概率遇到过这样的需求:实现一个可拖拽的小组件,比如掘金页面右下角的反馈图标。
可拖拽小组件要怎么做?easy-drag 就是为解决这个问题诞生的!
原理
首先,我们要确定怎样实现偏移效果,这里无非就两种:
一种是利用绝对定位,拖拽时调整
top
和left
值,但是这种方案依赖父组件的定位方式另一种是利用
transform
,拖拽时调整元素的偏移向量,这种方案不依赖父组件的定位方式
这里我们当然要选择后者,因为后者可以适应更多的场景。
然后,我们要确定怎么计算偏移向量,这里我们监听mouse
事件来实现:
监听元素的
mousedown
事件,记录元素初始偏移位置;监听文档的
mousemove
事件,根据鼠标位移向量修改元素的偏移位置;监听文档的
mouseup
事件,重置数据。
这样我们就确定了大致方案。
实现
大致方案确定了,具体的实现就是细枝末节了,但是需要注意的点还是不少的:
元素原先有 transform 属性怎么办?
因为元素原先是可以设置transform
属性的,所以我们设置的transform
属性必须要在元素样式的transform
基础上叠加,所以需要用到window.getComputedStyle(element).transform
,然后拼接transform
属性
元素怎么跑偏了?
原因是拼接transform
属性时将拖拽的translate3d
拼接到了原有的transform
值后面,而原有的ratate
会将元素的坐标系旋转,导致再施加平移效果时就会“跑偏”。
将平移效果加到原有transform
值前面就可以避免这个问题。
性能怎么样?
是不是如丝般顺滑,因为translate3d
属性会使浏览器为元素单独生成图层,而通过translate3d
修改元素的位置时只会触发浏览器的重新合成图层,并不会触发重排重绘,所以自然非常顺滑~
使用方式
安装
npm i easy-drag
使用
import enableDrag from 'easy-drag'; const disableDrag = enableDrag(document.querySelector('.draggable')); disableDrag();复制代码
功能
easy-drag 支持取消拖拽
easy-drag 支持设置拖拽范围,默认不可超出
document.body
easy-drag 支持设置拖拽点,适用场景:弹窗需要设置为可拖拽的,但只能拖拽标题区域
easy-drag 支持设置自定义回调,包含
onDragStart
、onDrag
、onDragEnd
作者:移步西龙
链接:https://juejin.cn/post/7019207342117879816