Monday, December 14, 2015

javascript drag and drop: problems with dragleave

i don't have much experience with javascript and jquery, but recently i started playing with MeteorJS (and i love it - but about this in a different post).

i'm dragging something onto a div and want an effect of openning jaws. yes, thats right - jaws :) i settled with jquiery-ui toggle, but then decided that addClass/removeClass would be good enough.

and here started the trouble with drag events - as for a single drag over my (large) area i got too many enter/over/leave/exit events, that were causing the "jaws" to toggle non-stop instead of opening on dragenter and closing on dragexit (or dragend - but i never got this event fired; or dragstop - which should be jquiry's killer drag finish event - alas not fired either for some reason).

it took me some time to realize that the nested div and other elements withing the target div were causing this constant enter/leave madness, which was breaking my flow.

so what to do? in an enviroment clean as this one everything is nice and clean, so how can i stop the sub elements from breaking my drag flow? it seems impossible...

so my idea to solve it is based on this:

my events are handled for the div id:
'dragenter #sidebar': function(e, t) {


but what if i'd be able to differentiate between event targets and fire the closing 'close jaw' event when a really non related target sends one of the drag events? but how? here's how:

as you can see, for example on mozilla's site, the drag events have a currentTarget property, but also a relatedTarget property - which it turns out we can use to detect the origin of the previous event - that is, for example - for a dragLeave event: the element that drag operation has left.

so now, our event catcher/handler becomes like this:
  'dragleave .drag-leave': function(e, t) {
    e.stopPropagation();
    e.preventDefault();


aaaaand - we need to add to all subelements of our div the subclass .drag-leave, so that we can check with a simple
if (e.relatedTarget && e.relatedTarget.className.search("drag-leave") == -1) {
      console.log(e.relatedTarget);
      $('#animTarget').removeClass("myClass", 1000, "easeOutSine");
    }



if we should close the jaw and finalize our effect.

so

is this a silly approach? please let me know, for now it works for me