微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用onMouseMove时,ReactJS中的自定义可拖动组件太慢

如何解决使用onMouseMove时,ReactJS中的自定义可拖动组件太慢

我正在尝试创建可拖动的preact组件。如果光标快速移动,我当前的实现将中断。这是代码

export { Draggable };

import { h } from "preact";
import { useState } from "preact/hooks";

const Draggable = (props: any) => {
    const [styles,setStyles] = useState({});
    const [diffPos,setDiffPos] = useState({ diffX: 0,diffY: 0 });
    const [isDragging,setIsDragging] = useState(false);

    const dragStart = (e: MouseEvent): void => {
        const boundingRect =
            (e.currentTarget as HTMLElement).getBoundingClientRect();

        setDiffPos({
            diffX: e.screenX - boundingRect.left,diffY: e.screenY - boundingRect.top,});

        setIsDragging(true);
    }

    const dragging = (e: MouseEvent): void => {
        if (isDragging === true) {
            const left = e.screenX - diffPos.diffX;
            const top = e.screenY - diffPos.diffY;

            setStyles({ left: left,top: top });
        }
    }

    const dragEnd = (): void => {
        setIsDragging(false);
    }

    return (
        <div
            class="draggable"
            style={{ ...styles,position: "absolute" }}
            onMouseDown={dragStart}
            onMouseMove={dragging}
            onmouseup={dragEnd}
        >
            {props.children}
        </div>
    );
}

我试图通过创建mouseup事件侦听器来修复它,但是如果我将鼠标移到快速位置,该元素将停止拖动。

这是我尝试的解决方法

export { Draggable };

import { h } from "preact";
import { useState } from "preact/hooks";

const Draggable = (props: any) => {
    const [styles,});

        setIsDragging(true);

        // ------------------------------------------------------------ Added an event listener
        document.addEventListener("mouseup",dragEnd,{ once: true });
    }

    const dragging = (e: MouseEvent): void => {
        if (isDragging === true) {
            const left = e.screenX - diffPos.diffX;
            const top = e.screenY - diffPos.diffY;

            setStyles({ left: left,position: "absolute" }}
            onMouseDown={dragStart}
            onMouseMove={dragging}
            // -------------------------------------------------------- Removed onmouseup
        >
            {props.children}
        </div>
    );
}

解决方法

问题在于,每次移动鼠标时onMouseMove()都会触发,因此,如果您非常缓慢地移动200像素以上,则将进行200次迭代。尝试使用onDragStartonDragEndFull working demo.

最终,您的更改将在render() ...

 return (
   <div
     class="draggable"
     style={{ ...styles,position: "absolute" }}
     onDragStart={(e) => dragStart(e)}
     onDragEnd={(e) => dragging(e)}
     draggable={true}
   >
     {props.children}
   </div>
 );

我使用dragEnd(),因此实际上只有两个事件会随着拖动而触发:开始和结束。每次移动时都会触发MouseMove,在拖动过程中可能会发生数百次。

此外,通过为其提供额外的draggable={true}参数,浏览器会将其视为自然可拖动的项目(即,所拖动项目的半透明版本将在视觉上出现在光标的位置,当用户在周围拖动元素时。)

最后,为了加快速度,我删除了eventListenerdragEnd的{​​{1}}。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。