Jump to content
Search Community

Draggable PointerEvent target is non-draggable element

slopps test
Moderator Tag

Recommended Posts

Very rarely, about 1 out of 100 times (sometimes you have to re-run the pen even), if you try to drag these items around very rapidly (as in click, drag, release and immediately click and drag again, over and over)

Edit: to replicate consistently, place the mouse on the last pixel on any edge of DragItem1 (so the very first pixel where your mouse turns into a drag icon), then drag away from that edge (so if you choose bottom edge, drag downward). You will see via the console logs that the PointerEvent target inside onDragStart is a totally non-draggable element.

In the onDragPress, the target is correctly '.drag-item', whereas in onDragStart, the target is 'drag-item__wrapper' (and sometimes other elements, depending), which is not a Draggable.

 

I put in a console warning to show when this happens.

 

I feel like this is happening because once the mouse moves 1 pixel away, it is no longer over/touching the drag item but instead over what's under the mouse? So perhaps I should move most my logic out of onDragStart?

 

Screenshot of console below (the error about update() is happening because the target is not a Draggable).

 

Any help is greatly appreciated!

 

 

Capture.JPG

See the Pen abbgQQx by sammyjoe (@sammyjoe) on CodePen

Link to comment
Share on other sites

Solved.

While the PointerEvent target is still showing non-Draggable, I was able to stop the errors by setting this.$currentDragItem in onDragPress instead of onDragStart.

 

I now realize this is not an issue with Draggable as is it is merely passing along the PointerEvent, which is reflecting what the mouse is currently over. I'm also scoping my callbacks differently so that I'm not able to get the draggable instance from 'this'.

If scoped normally, you wouldn't need to rely on the PointerEvent to get the current drag item, as you could use 'this' to get the Draggable instance.

 

Hope this helps someone in the future!

  • Like 1
Link to comment
Share on other sites

It's not a good idea to get the draggable element from the event.target. The event.target can be another element, which is why you are gettings errors.

 

3 hours ago, slopps said:

I'm also scoping my callbacks differently so that I'm not able to get the draggable instance from 'this'.

 

Your scoping is a little off. Using this inside a function like that is the same as using window. And that's only because you aren't using "use strict";. If you were using "use strict"; inside your code, this would be undefined.

 

So you are just adding everything to the global window object.

console.log(this === window); // true

 

To correctly use this inside a function like you're doing, you would need to create an instance using new.

 

var app = new App();
app.logMsg(); // Hello, World!

function App() {
  
  this.msg = "Hello, World!"
  
  this.logMsg = () => {
    console.log(this.msg);
  }
}

 

If you need to get the target from a scoped callback, you can use bind() instead of callbackScope.

 

var dragItems = Array.from(document.querySelectorAll(".drag-item"));
    
this.draggables = dragItems.map((item) => {

  return new Draggable(item, {
    type: "top,left", 
    bounds: document.body,
    onPress: this.onDragPress.bind(this, item),
    // onRelease: this.onDragRelease.bind(this, item),
    onDragStart: this.onDragStart.bind(this, item),
    onDragEnd: this.onDragEnd.bind(this, item),
    onDrag: this.onDrag.bind(this, item),
    allowContextMenu: true
  });
});

 

Now the target and event will be passed into your callbacks.

 

onDragStart = function(target, e) {
  ...
};

 

Now you'll always get the correct target.

 

See the Pen b7d1e259b804116ebecddd4a99b031e4 by osublake (@osublake) on CodePen

 

 

  • Like 4
Link to comment
Share on other sites

Thank you Blake! That's a great point about binding, that should've occurred to me.

 

Great points on the scoping too; thank you for pointing that out. That was due to porting this as quickly as possible to codepen from a component that exists within a larger app, where the "this" context is referring to the component which is encapsulated within a commonjs module, which is created using new. I admittedly did a poor job on the pen...

 

Thanks so much for the quick and thorough response!

  • Like 2
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.
×
×
  • Create New...