| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 | import React, { useState, useImperativeHandle, forwardRef } from "react";// DraggableButton 组件const DraggableButton = forwardRef<HTMLDivElement, { children: React.ReactNode }>(({ children }, ref) => {    let homePos = localStorage.getItem("homePos");    let initPos = homePos ? JSON.parse(homePos) : { right: 200, top: 0 };    const [position, setPosition] = useState(initPos);    const [offset, setOffset] = useState({ x: 0, y: 0 });    const handleDragStart = (e: React.DragEvent) => {        const rect = e.currentTarget.getBoundingClientRect();        setOffset({            x: e.clientX - rect.left,            y: e.clientY - rect.top        });    };    const handleDrag = (e: React.DragEvent | any) => {        if (e.clientX === 0 && e.clientY === 0) return; // 忽略拖动结束时的最后一个事件        const newRight = window.innerWidth - (e.clientX - offset.x + e.currentTarget.offsetWidth);        const newTop = e.clientY - offset.y;        setPosition({ right: newRight, top: newTop });    };    const handleDragEnd = (e: React.DragEvent | any) => {        const newRight = window.innerWidth - (e.clientX - offset.x + e.currentTarget.offsetWidth);        const newTop = e.clientY - offset.y;        setPosition({ right: newRight, top: newTop });        localStorage.setItem("homePos", JSON.stringify({ right: newRight, top: newTop }));    };    // 使用 useImperativeHandle 将 DOM 节点暴露给父组件    useImperativeHandle(ref, () => divRef.current!);    const divRef = React.useRef<HTMLDivElement>(null);    return (        <div            ref={divRef}            draggable            onDragStart={handleDragStart}            onDrag={handleDrag}            onDragEnd={handleDragEnd}            style={{                position: 'fixed',                right: position.right,                top: position.top,                cursor: 'move',                zIndex: 1000            }}        >            {children}        </div>    );});export default DraggableButton;
 |