useDraggable
元素拖动
Usage
Fixed Demo
实时编辑器
function Demo() { const el = useRef<HTMLDivElement>(null); const [initialValue, setInitialValue] = useState({ x: 200 / 2.2, y: 120 }); useEffect(() => { setInitialValue({ x: window.innerWidth / 2.2, y: 120 }); }, []); const [x, y, isDragging] = useDraggable(el, { initialValue, preventDefault: true, }); return ( <div> <p style={{ textAlign: "center" }}>Check the floating boxes</p> <div ref={el} style={{ position: "fixed", cursor: "move", zIndex: 10, touchAction: "none", padding: 10, border: "solid 1px", left: x, top: y, }} > {isDragging ? "Dragging!" : "👋 Drag me!"} <div> I am at {Math.round(x)}, {Math.round(y)} </div> </div> </div> ); };
结果
Loading...
Relative Demo
实时编辑器
function Demo() { const el = useRef<HTMLDivElement>(null); const scope = useRef<HTMLDivElement>(null); const initialValue = { x: 200 / 2.2, y: 120 }; const [x, y, isDragging, setPosition] = useDraggable(el, { initialValue, preventDefault: true, containerElement: scope, }); return ( <div ref={scope} style={{ width: 500, height: 500, border: "1px solid blue", position: "relative", }} > <button style={{ textAlign: "center" }} onClick={() => { setPosition({ x: 250, y: 250, }); }} > Set Position </button> <div ref={el} style={{ position: "absolute", cursor: "move", zIndex: 10, touchAction: "none", padding: 10, border: "solid 1px", left: x, top: y, whiteSpace: "nowrap", }} > {isDragging ? "Dragging!" : "👋 Drag me!"} <div style={{ whiteSpace: "nowrap" }}> I am at {Math.round(x)}, {Math.round(y)} </div> </div> </div> ); }
结果
Loading...
API
useDraggable
Returns
readonly [number, number, boolean, React.Dispatch<React.SetStateAction<Position>>]
: 包含以下元素的元组:
- x
- y
- 元素是否在拖动中
- 设置元素的位置
Arguments
参数名 | 描述 | 类型 | 默认值 |
---|---|---|---|
target | dom对象 | BasicTarget<HTMLElement | SVGElement> (必填) | - |
options | 可选参数 | UseDraggableOptions | undefined | - |
UseDraggableOptions
参数名 | 描述 | 类型 | 默认值 |
---|---|---|---|
exact | 仅当直接单击元素时才开始拖动 | boolean | false |
preventDefault | 阻止默认事件 | boolean | false |
stopPropagation | 阻止事件冒泡 | boolean | false |
draggingElement | 将“pointermove”和“pointerup”事件附加到的dom元素 | BasicTarget<HTMLElement | SVGElement> | window |
containerElement | 设置拖拽容器边界 | BasicTarget<HTMLElement | SVGAElement> | undefined |
handle | 触发拖动事件的dom元素 | RefObject<HTMLElement | SVGElement> | target |
pointerTypes | 监听的事件类型 | PointerType[] | ['mouse', 'touch', 'pen'] |
initialValue | 初始的元素位置 | Position | { x: 0, y: 0 } |
onStart | 拖动开始时的回调。 返回“false”以防止拖动 | (position: Position, event: PointerEvent) => void | false | - |
onMove | 拖动时候的回调 | (position: Position, event: PointerEvent) => void | - |
onEnd | 拖动结束的回调 | (position: Position, event: PointerEvent) => void | - |
BasicTarget
export type BasicTarget<T extends TargetType = Element> = (() => TargetValue<T>) | TargetValue<T> | MutableRefObject<TargetValue<T>>;
TargetValue
type TargetValue<T> = T | undefined | null;
TargetType
type TargetType = HTMLElement | Element | Window | Document | EventTarget;
PointerType
export type PointerType = 'mouse' | 'touch' | 'pen';
Position
export interface Position {
x: number;
y: number;
}