我有 Draggable 元素,在它的内部,我有一个带有 onClick 事件的组件。拖动结束时,触发点击事件。 我的可拖动元素如下所示。我使用了一个名为 react-draggable 的包。
<Draggable
position={this.state.realPosition}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}
disabled={this.state.isDialogOpen}
bounds="parent">
<div style={{"width":"fit-content"}}>
<Helmet getDialogStatus={this.handleClick} />
</div>
</Draggable>
我在 Helmet 组件内有 onClick 事件,它会打开一个对话框。当我拖动并释放该元素时,将打开此对话框。我的问题是如何防止此操作以及如何将这些操作与事件分开?
谢谢。
const [isDragging, setIsDragging] = useState<any>(false);
const eventControl = (event: { type: any; }, info: any) => {
if (event.type === 'mousemove' || event.type === 'touchmove') {
setIsDragging(true)
}
if (event.type === 'mouseup' || event.type === 'touchend') {
setTimeout(() => {
setIsDragging(false);
}, 100);
}
}
然后,
<Draggable
bounds="parent"
onDrag={eventControl}
onStop={eventControl}
> ...
我会在持有
Draggable
、isDragging
的组件中设置一个状态,并将其传递给头盔组件。
如果 isDragging 则禁用任何点击事件。
您可以通过使用状态变量 isDragging 来跟踪组件是否被拖动来区分拖动和单击。使用react-draggable组件的onDrag和onStop事件来管理此状态。这是一种有效的方法,感谢 @lakjeewaWijebandara
const [isDragging, setIsDragging] = useState(false);
const eventControl = (event) => {
if (event.type === "mousemove" || event.type === "touchmove") {
setIsDragging(true);
}
if (event.type === "mouseup" || event.type === "touchend") {
setTimeout(() => {
setIsDragging(false);
}, 100);
}
};
return (
<Draggable bounds="parent" onDrag={eventControl} onStop={eventControl}>
<div
onClick={() => !isDragging && handleOpen()}
onTouchEnd={() => !isDragging && handleOpen()}
>
// Button content here ...
</div>
</Draggable>
);
在该方案中,当检测到mousemove或touchmove事件时,isDragging被设置为true,表示进行拖动操作。当检测到 mouseup 或 touchend 事件时,isDragging 在一小段延迟后被设置为 false,表示拖动操作已结束。单击或触摸按钮时,仅当 isDragging 为 false 时才会调用handleOpen 函数,以确保在拖动操作期间不会触发该函数。
尝试通过使用事件对象在
event.stopPropagation();
和 this.handleDrag
事件处理程序中使用 this.handleStop
。他们可能会解决您的问题。
创建一个引用来跟踪鼠标指针的 x 和 y 位置。如果位置发生了一定阈值的变化,那么我们可以认为鼠标正在拖动,否则就是单击。
const pointer = useRef({x: 0, y: 0});
const onMouseDown = (e) => {
pointer.current = {x: e.clientX, y: e.clientY};
}
const onMouseUp = (e) => {
const {x, y} = pointer.current;
if (Math.abs(e.clientX - x) < 10 && Math.abs(e.clientY - y) < 10) {
// your click function here
}
}
然后在特定的div上添加onMouseDown和onMouseUp事件
<div onMouseDown={onMouseDown} onMouseUp={onMouseUp}>{...}</div>
为了防止在 React 中拖动 div 中的元素后触发单击事件,可以使用区分“单击”和“拖动”的技术。单击是一种鼠标事件,在用户按下(mousedown)和释放(mouseup)鼠标按钮之间没有明显的移动。阻力涉及这两个事件之间的位移。
其想法是在 mousedown 事件中记录鼠标坐标,并将其与 mouseup 事件中的鼠标坐标进行比较。如果坐标之间的距离大于某个阈值(比如几个像素),就认为是拖动,可以阻止点击事件。
const [isDragging, setIsDragging] = useState(false);
const [startPosition, setStartPosition] = useState({ x: 0, y: 0 });
const handleMouseDown = (e) => {
setIsDragging(false);
setStartPosition({ x: e.clientX, y: e.clientY });
};
const handleMouseMove = (e) => {
const distance = Math.sqrt(
Math.pow(e.clientX - startPosition.x, 2) + Math.pow(e.clientY - startPosition.y, 2)
);
if (distance > 5) {
setIsDragging(true); // Consider it a drag if the threshold is exceeded
}
};
const handleMouseUp = () => {
if (!isDragging) {
console.log("Div clicked");
}
};
普鲁巴
<div
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
> Drag or click here </div>