-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Lift event / start dragging after touch delay #289
Comments
I'm also interested in this feature. Our use case is the same; we have an area where you can scroll, and it would be nice a delay. There is an old closed PR, #225 Are there any changes that would have to be done to the PR to be a viable solution? |
Same UC here, fwiw. Hacked in a setTimeout workaround for now, but I admittedly don't feel great about that solution :) Edit: see better option below. |
I'm in the same boat. Trying to make scrolling on mobile not kick off drags. @ramiabraham how does your workaround work? |
Hope that helps! |
@Rigoleto this is a great workaround. In my case, I'm building a todo list, and pretty much the whole UI is draggable. Does this mean putting a mask over the whole viewport? And if I do that, won't I affect normal link clicks? And did you adapt the jQuery scroll intention plugin? |
I would also prefer if we had control over triggering drags with different events. We use hammerjs for example and so would prefer to activate drags on press rather. The lift api could be the solution |
I also needed this feature in my project to manage scroll and drag'n drop on iPad. For anyone interested, I managed to make it work and referred to this commit: b604c08 I edited the last dragula.js version (3.6.8) and added this code before
and Also, add this in your JavaScript :
and as a dragula option :
Don't forget to initialize dragula like this: I don't know why @bevacqua removed this from the API, it's working completely fine on my side 👍 . |
Great stuff thanks @zetura ! Ill give it a shot once I dev this further, I've also forked dragula and started customizing the code. |
Delay is crucial for my workflow as well. Can it be reinstated as an option? |
I need it as well |
@zetura I haven't played with that code but what do you think about submitting a pull request on that? Seems like plenty of folks want this functionality. |
I quickly created a PR for this using the logic @zetura provided - I still need to test it properly |
@patrickfatrick @linearza I'm actually looking to implement the functionality as a unique option (liftDelay). I just have an issue that if you wait and then scroll, you have the scroll + the mirror object. I think that @bevacqua removed the functionality because you need to put a lot of code in your implementation (that's why i'm looking to have a single option). :) |
@patrickfatrick @linearza Take a look at this commit : regislutter@d246524 You just have to put the option "liftDelay" for this to work: |
Aha - I havent worked on this in a while - but I just remembered why this implementation wasnt working for us. In our case we need to trigger a lift on press - but dragula is tightly coupled with its own gestures and the mapping of mouse to touch events. This causes a problem in our case since |
@zetura I tried out your change on a new ipad and it almost works but not quite. It seems to be jammed up with a scroll event where the item is trying to drag and the container is trying to scroll all at the same time making it kinda unusable. My setup has multiple container columns that scroll horizontally off the screen (horz scroll on the columns parent container). Each column has zero or many vertically stacked items (a column can be vert scroll if it overflows). I tap and hold an item to be dragged, wait for the lift to kick in and then start dragging around. Although the drag kinda works it seems to hook with the scroll and as I drag, the container(s) are scrolling as well or at least attempting to. I'm glad you gave this a shot though. I don't see anything inherently wrong with the code and it is how I would have gone about it as well. I can't think of a different approach right now but if I do I will chime back in on this thread. Happy to give other ideas a whirl to. Oh, and I did discover a kinda workaround to the whole thing. On an iPad/iPhone you can simply do a 2 finger scroll to scroll the containers. Dunno about other touch devices though. |
In case it helps anyone, I've been able to manage this problem by exposing the grab method from the dragula API. I've created a pull request for this change and written a short explanation of my workaround. You can read it here: #375 |
I had the same problem and came up with the following solution, perhaps this is helpful for others. Since in 3.0.0 drag events won't start if return {
restrict: "A",
link: function( scope, element ) {
var touchTimeout,
draggable = false;
element.on( "touchmove mousemove", function( e ) {
if ( !draggable ) e.stopPropagation();
});
element.on( "touchstart mousedown", function( event ) {
touchTimeout = $timeout( function() {
draggable = true;
}, 1000 );
});
element.on( "touchend mouseup", function( event ) {
$timeout.cancel( touchTimeout );
draggable = false;
});
}
}; |
@haschu's solution worked pretty well for me, with some modifications. Mainly, dragging before the delay timer makes it 'draggable' will then cancel the timer, which solves an issue where a mouse dragging the item would appear to have no effect at first, and then further mousemoves would have the item 'catch up'. And this one's for Angular 2 and TypeScript, also obviously it's enabled only for touch devices. import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({ selector: '[delayDragLift]' })
export class DelayDragLiftDirective {
dragDelay: number = 200; // milliseconds
draggable: boolean = false;
touchTimeout: NodeJS.Timer;
@HostListener('touchmove', ['$event'])
// @HostListener('mousemove', ['$event'])
onMove(e: Event) {
if (!this.draggable) {
e.stopPropagation();
clearTimeout(this.touchTimeout);
}
}
@HostListener('touchstart', ['$event'])
// @HostListener('mousedown', ['$event'])
onDown(e: Event) {
this.touchTimeout = setTimeout(() => {
this.draggable = true;
}, this.dragDelay);
}
@HostListener('touchend', ['$event'])
// @HostListener('mouseup', ['$event'])
onUp(e: Event) {
clearTimeout(this.touchTimeout);
this.draggable = false;
}
constructor(private el: ElementRef) {
}
} <!-- in your template -->
<div class="some-draggable-div" delayDragLift></div> |
Have implemented this in an ES5 react project and I think it's broken in >= iOS 11.3, I cannot stop the propagation of the Class methods: handleTouchStart: function () {
var _this = this;
this.touchTimeout = setTimeout(function () {
_this.isDraggable = true;
}, this.dragDelay);
},
handleTouchMove: function (e) {
if (!this.isDraggable) {
// this doesn't seem to do anything
e.stopPropagation();
}
},
handleTouchEnd: function () {
clearTimeout(this.touchTimeout);
this.isDraggable = false;
}, Within the render method: <div
className='draggable-item'
onTouchMove={this.handleTouchMove}
onTouchStart={this.handleTouchStart}
onTouchEnd={this.handleTouchEnd}
>
{this.props.children}
</div> The call to stop the propagation of the event in |
Reverted to |
aaaand have discovered that this breaks a all of my ordering flows. Back to the drawing board. Am now back on |
@rohan-deshpande @cormacrelf @haschu Tried your solution but could not make it work. |
@radenkozec Sorry, my workaround is almost 4 years old and I've never used dragula since... 😕 |
any updates on this issue ? |
any way to use delay in newest dragula? |
In order to make this library a bit more touch friendly it will help to be able to delay dragging until after a second of holding the finger down without moving. This way a user can drag if they want or also scroll an area on a touch device.
I see there was a commit with a new method called "lift" which will work perfectly for me. When will this be available in dist folder?
The text was updated successfully, but these errors were encountered: