Jump to content


New Draggable instance immediately after startDrag() doesn't "click" right with inline JS or starting overlapped element.

Recommended Posts

Hey guys, it's Beholder4096, back again with another obscure bug. This time, the mind-boggling infestation here has taken me to discover two possible ways this bug can be demonstrated, so please bear with me..


I have an object (green in the CP example) which I need to make draggable, after user clicks another object, that is overlapping it (yellow in the example). When the overlapping yellow box on top is clicked, the draggable instance of green is created and green becomes draggable. So far so good.

However, if I rerun the example and click the yellow and hold mouse button without movement and then release, the onClick of the draggable object doesn't fire! (all other events do fire, even onDragEnd() even though we were not dragging). I know it looks like it's for obvious reason.. But this behavior makes UI extremely inconsistent in my use case where I am very depending on this to work! Here the user can either (1) click the yellow overlapping object and release immediately (and the green object runs the onClick as it should) or the user can (2) click the yellow, hold the mouse for dragging and drag the green object to the destination.


I have noticed that the exact same bug happens when clicking ONLY green object and releasing it without movement, but only when the Draggable.create() code is in the inline javascript onmousedown event. Please refer to the CP example where I have implemented both ways the bug can show.


I must stress all of the other draggable events run ok, even the onPress event, which is also quite illogical since when I click the yellow box I never pressed on the green. And in the case of inline-js, I literally click the green and onPress registers but onClick doesn't work. While onDragEnd fires as well even though I totally didn't drag, just clicked. Aah, these crazy bugs, how come no one ever notices them?



Please, PLEASE fix this as I would have to do a super-crazy workaround if the 2-box overapping scenario didn't work as it should. 



Click yellow box or green box. Do not drag.

What happens: pretty much nothing, just draggable element gets to the front.

What is expected: the onClick event of the draggable green box should fire and show alert.


See the Pen PoRWXaQ by Beholder4096 (@Beholder4096) on CodePen

  • Like 1
Link to comment
Share on other sites

I totally get that you're frustrated, but using insulting and inflammatory phrasings like "mind-boggling infestation", "Aah, these crazy bugs, how come no one ever notices them?", and video clips that attempt to drive home your point about these things being obvious to anyone with half a brain...well, it doesn't go over well on the receiving end. 


I've been doing this long enough to see plenty of situations where a valid argument could be made for either of two behaviors, but inevitably the "right" behavior is the one that you want in your particular project :) It's hard to see the other perspectives. But I'm often in the position of having to field all the different pitches for various developers' use cases which often conflict with each other. 


I'm not faulting you for arguing your case or being frustrated. Let me just explain why I don't think it's fair to call this an obvious "bug"...


A "click" is generally when the user:

  1. Presses down on the element (not happening in your case...but we're forcing a fake of that because you called .startDrag() which implies a press)
  2. DOES NOT DRAG (in your case you are literally calling .startDrag(), thus overriding Draggable's internal toggle)
  3. Releases on the same element that was pressed

So there are a bunch of rules you're breaking here in "typical" click scenarios. This is highly unusual which is why "nobody else noticed". 


The key here is that you're forcing the start of a drag with .startDrag() but also wanting it to act like no dragging occurred. Internally, part of the logic is "if the element had been dragged when released DON'T fire the onClick" (for obvious reasons). But you're calling that a bug. I'd argue it is the appropriate behavior.  


If I implement the behavior you're requesting, I wouldn't be surprised if within a few months, a different user posts in these forums, blasting us with "aah, these crazy bugs! I called .startDrag(), so why is my onClick firing??? Doesn't anybody notice these things?! I need this to be fixed immediately for my project to work properly." 


From what I can tell (and please correct me if I'm misunderstanding), this boils down to "should onClick() be called even after a drag was forced with .startDrag()...and it's unintuitive to fire a click if there was a drag?"


Side note: I really appreciate your excellent minimal demos. Thank you for taking the time to create those. Super clear and helpful. And thanks for reporting things that you believe are bugs, because ultimately they can help make the tools better for everyone. 

  • Like 2
Link to comment
Share on other sites

Oh, please don't be insulted, I am just trying to be more funny in this dry and totally logical work.. Will Ferrell is my favorite, as well as this clip. But I understand this is your work and if you want me be 100% here on the logical/dry side, I am all for it, no big deal. I am sorry and I apologize for my behavior and that it felt like nuisance to you. I guess I kind of found it funny that I come up with these weird bugs in the weirdest circumstances.


Yes, this boils down to "should onClick be called after a drag was forced with .startDrag() when user clicked different element / and there was no actual drag?".


Take it from UI design point of view: imagine the yellow element as transparent label with just label text. Imagine the green box as an image of an actual thing. User can to click OR drag the image even if they click/drag on the label. I want the draggable object stay behind the label since if there is no Javascript, user can still rely on the label / submit button and submit the page with the proper action. I modified the CP example to better convey what I am describing here.


In the end, this probably cannot be categorized as a 'bug' but it quite certainly is an inconsistency. The green object can be dragged through the yellow label yet it cannot be "clicked through it". The green object can be clicked but not the very 1st time, when the draggable is being created, again on that time it can only be dragged. After that it can be clicked anytime. The cursor from this standpoint is also inconsistent: it changes to grab-hand when green object is dragged directly but never changes to grab-hand when green object is dragged via the yellow label. Or grab the green box and dragging it, move cursor slowly over the yellow label. If the cursor is an indication of an action that is currently going on (drag) then why would it change if the drag never ended? These inconsistencies are what I am after (to remove).


Thanks a lot for looking into this. It seems like a small thing but I believe that by ironing out these inconsistencies your software will be accessible to wider array of less experienced developers. I know what I am talking about, I found these problems very early in my Draggable / touch learning experience and it bogged me down for a few days before I realized that I might be doing nothing wrong and where the problem might be.




Link to comment
Share on other sites

2 hours ago, Beholder4096 said:

Oh, please don't be insulted, I am just trying to be more funny in this dry and totally logical work.. Will Ferrell is my favorite

No worries. I'm a big Will Ferrell fan too. Dry humor is my favorite. 


2 hours ago, Beholder4096 said:

I want the draggable object stay behind the label since if there is no Javascript, user can still rely on the label / submit button and submit the page with the proper action.

This is part of the problem. Normally, you could just set pointer-events: none on the element that's sitting on top (obscuring/absorbing pointer events) but it sounds like you're trying to treat multiple elements as if they are one...and also not one at the same time (they don't move together, but you click/press/release as if they're all one). 


This is also causing problems with the cursor - when you rollover the Draggable, of course that cursor should change but you're ALSO trying to make that cursor behavior happen on the element that sits in front and absorbs/obscures pointer events. You seem to be expecting Draggable to handle all of that custom logic for you automatically. I don't think that's reasonable or appropriate. You'd doing some highly unconventional, custom behavior. Sorta like if you stack two buttons right on top of each other and then expecting that clicking on the button in FRONT would also trigger events on the one behind, including hover. 


Many of the "fixes" you're requesting seem like they'd be considered "bugs" in other contexts. If something was dragged, it's not supposed to fire the onClick. The cursor is supposed to show while it's over the Draggable element...but you're asking it to force itself no matter what other element is hovered over. What if there's a hover cursor set on that other (interfering) element? Is Draggable supposed to make it impossible? 


I think that much of the non-standard behavior you're requesting be baked into Draggable is more appropriately handled by your own custom code outside Draggable. If you need help with some of that, just post a minimal demo with the challenge you're facing and I don't mind trying to help you solve it. 

Link to comment
Share on other sites

So in the end I've decided to side-step this issue and pretty much work around it by putting the label onto the object itself. That way the label will move with the object and I will have to make a clone of the object if I want to "put it elsewhere" (and return this one with label to its original place). It's not much more work but it's pretty much guaranteed to work as I need without unnecessary hiccups.


If I find anything that doesn't work according to what I think it should, I will make another minimal demo that you like so much. It's also my preferred way of unobfuscating problems and learning that way.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.