-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent click event after dragging #61
Comments
Same issue here, with an additional note: On Android/Chrome, the dragscrollstart event is triggered almost instantly, making it difficult to guess if we're on a click (touch) or a real drag. I had to use a trick to bypass this issue:
|
export default class DragScrollClickFix {
readonly DRAG_DELAY = 100; // This is the minimal delay to consider a click to be a drag, mostly usefull for touch devices
timer: NodeJS.Timeout | null = null;
dragging: boolean = false;
onDragScrollStart() {
this.timer = setTimeout(() => this.onTimer(), this.DRAG_DELAY);
}
onTimer() {
this.timer = null;
this.dragging = true;
}
onDragScrollEnd() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
setTimeout(() => this.dragging = false);
}
onClickCapture(e: MouseEvent) {
if (this.dragging) {
this.dragging = false;
e.preventDefault();
e.stopPropagation();
}
}
} In your JS: dragScrollClickFix = new DragScrollClickFix(); Then in your Vue template: @click.capture="e => dragScrollClickFix.onClickCapture(e)"
@dragscrollstart="dragScrollClickFix.onDragScrollStart()"
@dragscrollend="dragScrollClickFix.onDragScrollEnd()" |
Please let me know the version you are using
…On Mon, Feb 10, 2020, 5:35 AM OzoneGrif ***@***.***> wrote:
export default class DragScrollClickFix {
readonly DRAG_DELAY = 100; // This is the minimal delay to consider a click to be a drag, mostly usefull for touch devices
timer: NodeJS.Timeout | null = null;
dragging: boolean = false;
onDragScrollStart() {
this.timer = setTimeout(() => this.onTimer(), this.DRAG_DELAY);
}
onTimer() {
this.timer = null;
this.dragging = true;
}
onDragScrollEnd() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}
onClickCapture(e: MouseEvent) {
if (this.dragging) {
this.dragging = false;
e.preventDefault();
e.stopPropagation();
}
}
}
In your JS:
dragScrollClickFix = new DragScrollClickFix();
Then in your Vue template:
@click.capture="e => dragScrollClickFix.onClickCapture(e)"
@dragscrollstart="dragScrollClickFix.onDragScrollStart()"
@dragscrollend="dragScrollClickFix.onDragScrollEnd()"
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#61?email_source=notifications&email_token=ACP46PLKI4PZES5MQHUWUV3RCDKP5A5CNFSM4KLIY64KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOELHGIKI#issuecomment-583951401>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACP46PLUQN7FPG42MQC2M3LRCDKP5ANCNFSM4KLIY64A>
.
|
v1.10.2 here. |
Please try 2.0 and let me know because your issue will be fixed on version 2
…On Mon, Feb 10, 2020, 5:45 AM OzoneGrif ***@***.***> wrote:
v1.10.2 here.
Didn't test it on 2.0.0.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#61?email_source=notifications&email_token=ACP46PO5AZUGL2EYLXK4GODRCDLVDA5CNFSM4KLIY64KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOELHGVYQ#issuecomment-583953122>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACP46PKR2UK6E726H73XDZ3RCDLVDANCNFSM4KLIY64A>
.
|
Just tested, issue is still present in v2.0.0 |
Another possible fix is to do preventDefault() if the position of the mouse release is significantly far away (e.g. at least 5 pixels) from the start position. This is the solution https://github.com/ilyashubin/scrollbooster uses. Somewhat shorter version of @OzoneGrif's fix: import { dragscroll } from 'vue-dragscroll';
export default {
directives: {
dragscroll,
},
data: () => ({
dragged: false,
dragTimeout: null,
}),
methods: {
onDragStart() {
clearTimeout(this.dragTimeout);
this.dragged = false;
this.dragTimeout = setTimeout(() => { this.dragged = true; }, 100); // Minimal delay to be regarded as drag instead of click
},
onDragClick(e) {
if (this.dragged) {
e.preventDefault();
}
this.dragged = false;
},
},
}; It would be nice if one of these solutions (time comparison or distance comparison) would be implemented by default for links. |
thank you! let me try your solution |
I'm not able to get the same issue as you guys, someone can make a codepen that has exactly the issue ? |
@Tofandel and @OzoneGrif are you listening of the click event directly from the dragscroll element or on a child ? |
Child. You dragscroll the parent, using your mouse or touchscreen. When you release the drag, it triggers the click on the child component which is beneath the cursor or finger. |
We use this for a thumbtray of nuxt-links below a video. When you click to drag the tray, on mouseup it will follow the link that you cursor is on. |
This worked for me: On the anchor:
Methods: this.dragged = false; Style: |
I made a thin component <script setup>
// Avoid emitting click event when scrolldragging
let dragging = false;
let timer = null;
function start() {
timer = setTimeout(() => (dragging = true), 100);
}
function end() {
clearTimeout(timer);
setTimeout(() => (dragging = false));
}
function click(event) {
if (dragging) {
event.stopPropagation();
}
}
</script>
<template>
<div
v-dragscroll
@dragscrollstart="start"
@dragscrollend="end"
@click.capture="click"
>
<slot />
</div>
</template> |
Just adding this for anyone who uses Typescript. <script setup lang="ts">
// Avoid emitting click event when scrolldragging
let dragging = false;
let timer: ReturnType<typeof setTimeout> | null = null;
function start() {
timer = setTimeout(() => (dragging = true), 100);
}
function end() {
if (timer) {
clearTimeout(timer);
}
setTimeout(() => (dragging = false));
}
function click(event: MouseEvent) {
if (!dragging) return;
event.stopPropagation();
}
</script>
<template>
<div
v-dragscroll
@dragscrollstart="start"
@dragscrollend="end"
@click.capture="click"
>
<slot />
</div>
</template> Let me know I the above code can be improved. I'm no TS expert by any means. |
After a drag occurs, the click event should be stopped from firing with
stopImmediatePropagation
It otherwise leads to unexpected clicked elements within the scroll area
The text was updated successfully, but these errors were encountered: