关于react-draggable的使用总结
最近需要实现一个既支持PC端又支持H5端的悬浮可拖动按钮,自己实现的在页面渲染上总是感觉会延迟渲染,导致出现bug,网上很多文章,尝试过后总是会有一些小问题存在;
后来发现了react-draggable组件库,以下是我的一个使用探索;
参考资源: npm官方文档地址:
- npm地址:www.npmjs.com/package/rea…
- github地址:www.npmjs.com/package/rea…
最简单的使用就是:
<Draggable>
<div className={styles.btnStyle}>
拖拽按钮
</div>
</Draggable>
关于悬浮直接通过css样式定位去写就可以,这里简单举个例子:
.btnStyle
position: fixed
cursor: pointer
top: 72px
right: 20px
height: 48px
width: 48px
这是最简单的demo,可以先这么尝试以下,你就会发现,可拖拽的一个元素就实现了;
然后就根据自己的需求查看官方文档进行尝试吧!
onStart,onDrag,onStop
首先我想要的是一个可点击的按钮嘛,如果是拖动的操作的话,不会触发点击事件,如果没有拖动的话,偏要出发点击事件,所以便从官方文档提供的这三个事件下手啦;
- onStart: 开始拖动的时候调用的事件;
- onDrag: 拖动的时候调用的事件;
- onStop: 拖动结束的时候调用的事件;
所以我设置了一个判断是否可点击的状态值,如果开始拖动,就将这个状态置为TRUE,但是如果触发了onDrag事件,进行了拖动,就将这个值置为FALSE,然后在onStop事件中进行判断,是否可以触发click事件;
实现思路是这样的,下面是代码的实现:
import React, { useState } from 'react';
import Draggable from 'react-draggable';
import styles from './style.module.styl';
const DragBtnComponent = (props) => {
// 是否可点击
const [isClick, setIsClick] = useState(false);
const handleStart = () => {
console.log('拖动开始');
setIsClick(true);
};
const handleDrag = () => {
console.log('拖动ing');
setIsClick(false);
};
const handleEnd = () => {
console.log('拖动结束');
if (isClick) {
console.log('可点击');
}
};
return (
<Draggable onStart={handleStart} onDrag={handleDrag} onStop={handleEnd}>
<div className={styles.btn}>
<span>按钮</span>
</div>
</Draggable>
);
};
export default DragBtnComponent;
这样一个简单的悬浮可拖动的按钮就实现了;
bounds
官方文档对该属性的解释(百度翻译的):
bounds: 指定移动的边界值;可以设置的值:
parent:限制节点的offsetParent内的移动(位置为相对或绝对的最近节点);- 选择器:限制目标节点内的移动;
- 具有“左、上、右和下”属性的对象:指示了可拖动设备在每个方向上可以移动的距离;
在拖动的过程中,为了避免将按钮拖到屏幕外边,所以设置该属性,执行拖动按钮的活动范围;在这里我想要的效果是在整个屏幕内部拖动,所以采用最后一种方式,设定一个具有上下左右属性的对象;
这里记录一个我的误解:我刚开始直接这么设定的:bounds:{ left: 0, top: 0, right: 0, bottom: 0 };结果发现不能拖动了,然后又看了下API,发现这四个值指的是在该方向上的移动距离,不要像我这样粗心哦!
在观察DOM节点的时候发现,这个库是通过css转换来实现拖动的,即 transform: translate(0px, 0px);,而不是像我之前一样通过改动它的位置定位;
我们一般都会将按钮的初始位置放在页面的一个角落里,这里我是放在右上角,所以直接指定它向左和向下移动的距离,另外两个方向置为0就OK了;
还有一点就是结合translate(0px, 0px)函数,向X轴平移,填正数往右平移,填负数,往左平移;向Y轴平移,填正数往下平移,填负数,往上平移;
const left = target.offsetLeft - 20;
const bottom = document.documentElement.clientHeight - target.offsetTop - target.offsetWidth;
setBounds({ right: 0, top: 0, left: -left, bottom });
其他这次未用到的属性
-
allowAnyClick: 如果设置为“true”,将允许在非左键单击时拖动。
-
axis: 指定拖动的方向,可以设置的值为(
both: 默认值,水平垂直方向都可以拖动;x: 只能在水平方向拖动;y: 只能在垂直方向拖动;none: 不可拖动; );
-
cancel: 这个没怎么看懂,😂; 以下这三个属于一挂的:指定拖动元素的样式
-
defaultClassName: 默认值:'react-draggable'
-
defaultClassNameDragging: 默认值:'react-draggable-dragging'
-
defaultClassNameDragged: 默认值:'react-draggable-dragged'
-
defaultPosition: 拖动元素的默认位置,一般很少使用;
-
disabled: 如果设置为TRUE,将不触发拖动的处理,我理解的是拖动的开关;
-
grid: 官方给的解释是指定应该移动的x和y的值;
-
handle: 指定初始拖动的选择器;
-
offsetParent: 如果需要,您可以为阻力计算提供自己的offsetParent。默认情况下,我们使用DragTable的offsetParent。这对于具有奇数显示类型或浮动的元素很有用。
-
onMouseDown: 每当用户按下鼠标时调用。不管句柄或禁用状态。
-
nodeRef:
nodeRef也可以在<DraggableCore>上找到。 -
position: 将拖动元素变成受控的,自己指定位置;
-
positionOffset: 初始位置的一个位置偏移量;
-
scale: 指定要拖动此元素的画布的比例。这允许例如,当您通过放大或缩小时,您需要获得正确的拖动增量此元素父元素中的变换或矩阵。
总结
主要是关于react-draggable使用的一个探索,有时间的话还要继续研究一下这次没使用到的属性,还有看看源码,对比反思一下自己实现的,产生bug的原因和解决方案;