Open LennyLip opened 3 years ago
If it works for the first time - try to click several times, it's fired randomly
Also having this issue where clicking on child components on desktop correctly fire their event handler, but when I switch the view to any type of 'Responsive' in Chrome dev tools the event propagation seems to stop at the react-draggable component. Does this have something to do with MouseEvents vs. TouchEvents?
Not sure if this was the ideal solution but I noticed that tapping the child buttons on mobile mode was actually firing a touchstart
event instead of a click
event, so had to set up the buttons to have event handlers for both.
(Edited for clarity)
// component where dragging behavior is disabled under some circumstances.
// For mobile devices
// react-draggable disabled - fires both touchstart and click, so need to respond to only one of them
// react-draggable enabled - fires touchstart
// For desktop
// react-draggable disabled - fires click
// react-draggable enabled - fires click
...
const eventHandler = cb => {
return event => {
if (isMobile && event.type === 'touchstart') {
cb(event);
} else if (!isMobile && event.type === 'click') {
cb(event);
}
};
};
return (
<Button onClick={eventHandler(onClick)} onTouchStart={eventHandler(onClick)}>
<Icon type="arrow-left" />
</Button>
)
I have the same story, but I have an input, and click to move the cursor does not work on it. Unfortunately, the hacks will not work here, like changing the event. No ideas yet
Did you try to specify a cancel
selector and use it on the button?
I modified the example to show my problem.
cancel
- did not help
https://codesandbox.io/s/draggable-example-forked-vg1j3
Mobile browsers doesn't support proper mouse events
@myang5 's solution worked for me, thanks for the tip!
I simplified myang5's solution: onClick={(e) => handleSomething(e)} onTouchStart={(e) => handleSomething(e)}
I have the same case,Why is it designed like this ???
@myang5 's solution totally works in android chrome which I had exactly same issue but it would be awesome if we can get update with proper fixes. Thanks.
Also experiencing this issue.
Anybody knows what is causing this in react-draggable?
Ran into some stuff related to this today, probably caused by:
DraggableCore
, touchstart
events get preventDefault
called on them.click
event that would normally be dispatched after touchstart
DraggableCore
are registered manually via ref.addEventListener
because there's an issue calling preventDefault
in touch events registered via React stopPropagation
inside onStart
and onDrag
preventDefault
on touchmove
rather than touchstart
? I haven't had time to test this outI meet the same pro,and what should i do now?
`// index.js
<Draggable
axis="both"
handle=".handle"
defaultPosition={{ x: 0, y: 0 }}
position={positionXY}
bounds="html"
offsetParent={document.body}
scale={1}
onStop={handleDragStop}
>
<div className="handle">
<Box></Box>
</div>
</Draggable>
//Box.js
<div onClick={handleClickBox}>
</div>`
Calculate the duration and displacement of the entire dragging process. If the duration is within 300ms and there is no displacement, the onclick event is triggered.
handleDragStart = () => {
this.dragStartAt = Date.now();
setTimeout(() => {
this.dragStartAt = 0;
}, 300);
}
handleDragStop = (e: TouchEvent, data: DraggableData) => {
const { onClickBtn } = this.props;
const change = {
x: this.state.position.x - data.x,
y: this.state.position.y - data.y,
};
// There is no displacement and the touch time is within the preset range, which is regarded as a click event.
if (change.x + change.y === 0 && this.dragStartAt) {
onClickBtn();
}
this.setPosition(data);
}
<Draggable
onStart={this.handleDragStart}
onStop={this.handleDragStop}
/>
This may not be the most ideal solution, it would be really great if this problem could be solved soon.
Another version of @00Jane's, but for functional components:
const DragBox = ({ children }) => {
let [dragInfo, setDragInfo] = useState(null)
let handleDragStart = (e, data) => {
setDragInfo({
x: data.x,
y: data.y,
time: Date.now()
})
}
let handleDragStop = (e, data) => {
if (!dragInfo) return
let change = {
x: Math.abs(data.x - dragInfo.x),
y: Math.abs(data.y - dragInfo.y),
time: Date.now() - dragInfo.time
}
if (change.x + change.y <= 10 && change.time < 300) e.srcElement?.click?.()
}
return (
<Draggable onStart={handleDragStart} onStop={handleDragStop}>
{children}
</Draggable>
)
}
3 years for this bug, still now. 👎
Example: https://codesandbox.io/s/nervous-cdn-s2ufp
The desktop mode works ok. Mobile mode not fired the event (you can try on mobile or with dev tools - same result).