I'm mainly a backend engineer and have been trying to implement, and failing, a simple drag and drop for a slider I am making in React.
(我主要是一名后端工程师,一直试图为我在React中制作的滑块实现简单的拖放操作,但失败了。)
First I will show you the behavior without using debounce: no-debounce
(首先,我将向您展示不使用反跳的行为: 无反跳)
And here is the behavior with debounce: with-debounce
(这是debounce的行为: with-debounce)
The debounce I took from here with a little modification.
(我从这里进行了一些修改后的反跳。)
I think I have two problems, one is fast flickering, which debounce should solve, and the other is the incorrect left
which I cannot figure how to fix.
(我认为我有两个问题,一个是快速闪烁,应该解决抖动问题,另一个是我不知道如何解决的不正确left
。)
For some reason, onDrag, rect.left has all the left margins of the parents (100 + 10) added to it as well.(由于某些原因,onDrag,rect.left也添加了父母的所有左边界(100 + 10)。)
This happens on Chrome and Safari.(这发生在Chrome和Safari上。)
My question is, how do I make this drag and drop work?
(我的问题是,如何使这种拖放工作?)
What am I doing wrong?(我究竟做错了什么?)
My code is below:(我的代码如下:)
import React, {
Dispatch,
MouseEvent,
RefObject,
SetStateAction,
useEffect,
useRef,
useState
} from "react";
const useDebounce = (callback: any, delay: number) => {
const latestCallback = useRef(callback);
const latestTimeout = useRef(1);
useEffect(() => {
latestCallback.current = callback;
}, [callback]);
return (obj: any) => {
const { event, args } = obj;
event.persist();
if (latestTimeout.current) {
clearTimeout(latestTimeout.current);
}
latestTimeout.current = window.setTimeout(
() => latestCallback.current(event, ...args),
delay
);
};
};
const setPosition = (
event: any,
setter: any
) => {
const rect = event.target.getBoundingClientRect();
const clientX: number = event.pageX;
console.log('clientX: ', clientX)
// console.log(rect.left)
setter(clientX - rect.left)
};
const Slider: React.FC = () => {
const [x, setX] = useState(null);
const handleOnDrag = useDebounce(setPosition, 100)
return (
<div style={{ position: "absolute", margin: '10px' }}>
<div
style={{ position: "absolute", left: "0", top: "0" }}
onDragOver={e => e.preventDefault()}
>
<svg width="300" height="10">
<rect
y="5"
width="300"
height="2"
rx="10"
ry="10"
style={{ fill: "rgb(96,125,139)" }}
/>
</svg>
</div>
<div
draggable={true}
onDrag={event => handleOnDrag({event, args: [setX]})}
// onDrag={event => setPosition(event, setX)}
style={{
position: "absolute",
left: (x || 0).toString() + "px",
top: "5px",
width: "10px",
height: "10px",
padding: "0px",
}}
>
<svg width="10" height="10" style={{display:"block"}}>
<circle cx="5" cy="5" r="4" />
</svg>
</div>
</div>
);
};
Thank you.
(谢谢。)
ask by plumSemPy translate from so