如何解决使用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次迭代。尝试使用onDragStart
和onDragEnd
。 Full 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}
参数,浏览器会将其视为自然可拖动的项目(即,所拖动项目的半透明版本将在视觉上出现在光标的位置,当用户在周围拖动元素时。)
最后,为了加快速度,我删除了eventListener
中dragEnd
的{{1}}。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。